I'm getting the Rendered more hooks than during the previous render error in my react native application in this screen:
const HomeScreen = props => {
const [refreshing, setRefreshing] = useState(false);
if (props.data.loading) { // error shows its located here
return <Text>Loading...</Text>;
}
const onRefresh = useCallback(() => {
setRefreshing(true);
wait(2000).then(() => setRefreshing(false));
}, [refreshing]);
return (
<View style={styles.container}>
<FlatList
data={props.data.sample}
renderItem={({item}) => <Card {...item} user={props.data.user} />}
keyExtractor={item => item._id}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
/>
</View>
);
};
But when I move the useState below the if-statement:
const HomeScreen = props => {
if (props.data.loading) { // error shows its located here
return <Text>Loading...</Text>;
}
// moved here, change in the order of hooks...
const [refreshing, setRefreshing] = useState(false);
const onRefresh = useCallback(() => {
setRefreshing(true);
wait(2000).then(() => setRefreshing(false));
}, [refreshing]);
I get a Warning:
Warning: React has detected a change in the order of Hooks called by "HomeScreen". This will lead to bugs and errors if not fixed...
I get this error when my app hot reloads, but then when I Dismiss the warning and then force reload it doesn't appear. I just want to make sure that moving this below the if-statement is okay.
Also, I don't know why moving the useState will fix the original error message of rerendering?
Well, the error is obvious. Only useState is called when loading is true, and both useState and useCallback are called when it's not, so react complains about the number of hooks being inconsistent. The fix is most likely a fluke. This time no hooks are called when loading is true, and both of them are rendered when it's not. React's source code probably doesn't make the "number of hooks rendered" check if that number is zero initially, hence no error.
As the warning tells you, conditionally calling hooks (writing a return statement before any hook) is a bad idea. It might not break you app in this particular instance, but it's overall a bad practice. The hooks are called on every render and react needs to keep track of them properly.
I would put all the hooks (in this case both useState and useCallback) BEFORE the conditional return. I don't see any reasons not to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With