React Native:渲染的钩子比上一个渲染错误期间的钩子

问题描述 投票:1回答:1

在此屏幕上,我的本地应用程序响应中出现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将解决原始的重新呈现错误消息?

reactjs react-native react-hooks react-native-ios
1个回答
1
投票

嗯,错误很明显。当useState为真时,仅会调用loading,否则会同时调用useStateuseCallback,因此react抱怨钩子数量不一致。解决方法很可能是a幸。这次,当loading为true时,不会调用任何钩子,否则将不渲染它们。 React的源代码可能不会使“渲染的钩子数”最初检查该数字是否为零,因此没有错误。

如警告所言,有条件地调用钩子(在任何钩子之前编写return语句)是一个坏主意。在这种特定情况下,它可能不会破坏您的应用程序,但总体而言,这是一个坏习惯。在每个渲染器上都调用该挂钩,并做出响应以正确跟踪它们。

我会在条件返回之前放所有的钩子(在这种情况下,都是useStateuseCallback)。我看不出有任何理由不这样做。

© www.soinside.com 2019 - 2024. All rights reserved.