React Native:渲染了比之前渲染错误更多的钩子
React Native: Rendered more hooks than during the previous render error
我在这个屏幕上的 React Native 应用程序中收到 Rendered more hooks than during the previous render
错误:
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>
);
};
但是当我将 useState
移动到 if 语句下方时:
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]);
我收到警告:
Warning: React has detected a change in the order of Hooks called by "HomeScreen". This will lead to bugs and errors if not fixed...
我的应用程序热重载时出现此错误,但是当我关闭警告然后强制重载时它不会出现。我只是想确保将它移到 if 语句下面是可以的。
另外,我不知道为什么移动useState会修复重新渲染的原始错误消息?
嗯,错误很明显。当 loading
为真时只调用 useState
,当它不为真时 useState
和 useCallback
都会被调用,所以反应会抱怨钩子的数量不一致。该修复很可能是侥幸。这次当 loading
为真时没有钩子被调用,当它不是时它们都被渲染。 React 的源代码可能不会让 "number of hooks rendered" 检查该数字最初是否为零,因此没有错误。
正如警告告诉您的那样,有条件地调用挂钩(在任何挂钩之前编写 return 语句)不是一个好主意。在此特定情况下,它可能不会破坏您的应用程序,但总的来说这是一种不好的做法。钩子在每次渲染时都会被调用,React 需要正确地跟踪它们。
我会在条件 return 之前放置所有钩子(在本例中为 useState
和 useCallback
)。我看不出有什么理由不这样做。
我在这个屏幕上的 React Native 应用程序中收到 Rendered more hooks than during the previous render
错误:
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>
);
};
但是当我将 useState
移动到 if 语句下方时:
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]);
我收到警告:
Warning: React has detected a change in the order of Hooks called by "HomeScreen". This will lead to bugs and errors if not fixed...
我的应用程序热重载时出现此错误,但是当我关闭警告然后强制重载时它不会出现。我只是想确保将它移到 if 语句下面是可以的。
另外,我不知道为什么移动useState会修复重新渲染的原始错误消息?
嗯,错误很明显。当 loading
为真时只调用 useState
,当它不为真时 useState
和 useCallback
都会被调用,所以反应会抱怨钩子的数量不一致。该修复很可能是侥幸。这次当 loading
为真时没有钩子被调用,当它不是时它们都被渲染。 React 的源代码可能不会让 "number of hooks rendered" 检查该数字最初是否为零,因此没有错误。
正如警告告诉您的那样,有条件地调用挂钩(在任何挂钩之前编写 return 语句)不是一个好主意。在此特定情况下,它可能不会破坏您的应用程序,但总的来说这是一种不好的做法。钩子在每次渲染时都会被调用,React 需要正确地跟踪它们。
我会在条件 return 之前放置所有钩子(在本例中为 useState
和 useCallback
)。我看不出有什么理由不这样做。