【问题标题】:too many rerenders on using useState使用 useState 的重新渲染过多
【发布时间】:2023-03-26 03:13:01
【问题描述】:

我从主返回调用contacts函数。直到这里我才看到任何错误:

 const showContacts = React.useCallback(
    (data: UsersQueryHookResult) => {
      if (data) {
        return (
          <View style={styles.users}>
          </View>
        );
      }
    },
    [userData],
  );

  const contacts = () => {
    console.log('running');
    const { loading, error, data } = useUsersQuery({
      variables: {
        where: { id: 34 },
      },
    });
    console.log('DATA COMING', data);
    //setUserData(data);
    //console.log('contact name', data.users.nodes[0].userRelations[0].relatedUser.firstName);
  };

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <Container style={{ flex: 1, alignItems: 'center' }}>
        <Item style={styles.addToWhitelist}>
          <Icon
            name="add"
            onPress={() => navigation.navigate('AddContactTry')}
          />

          <Text style={styles.addToContactTitle}>Add contact</Text>
        </Item>
        <Text onPress={() => navigation.navigate('Home')}>Zurück</Text>
        <View style={{ width: moderateScale(350) }}>
          <Text>Keine Kontacte</Text>
        </View>
        {contacts()}
      </Container>
    </SafeAreaView>
  );
};

现在我想根据contacts的结果做一些条件渲染。但是,一旦我取消注释setUserData(data);,我就会收到一个错误,即重新渲染过多。我不明白我在showUsers做错了什么来得到这个错误。

编辑:

我试过了,但它给出了一个无效的钩子调用错误:

export const Whitelist: React.FunctionComponent = (props) => {

  const [userData, setUserData] = useState<UsersQueryHookResult>('');
 useEffect(() => {
    // Your function to fetch/get contacts
    const data = contacts();
    setUserData(data);
  }, [])

  const showContacts = React.useCallback(
    (data: UsersQueryHookResult) => {
      if (data) {
        return (
          <View style={styles.users}>
          </View>
        );
      }
    },
    [userData],
  );

  const contacts = () => {
    console.log('running');
    const { loading, error, data } = useUsersQuery({
      variables: {
        where: { id: 34 },
      },
    });
    console.log('DATA COMING', data);
    //setUserData(data);
  };



  return (
    <SafeAreaView style={{ flex: 1 }}>
      <Container style={{ flex: 1, alignItems: 'center' }}>
        <Item style={styles.addToWhitelist}>
          <Icon
            name="add"
            onPress={() => navigation.navigate('AddContactTry')}
          />

          <Text style={styles.addToContactTitle}>Add contact</Text>
        </Item>
        <Text onPress={() => navigation.navigate('Home')}>Zurück</Text>
        {/* {contacts()} */}
      </Container>
    </SafeAreaView>
  );
};

【问题讨论】:

  • 你应该只在事件发生时设置状态。如果直接在组件的渲染中使用它,您实际上是在创建一个无限的重新渲染循环(因为设置状态会重新渲染您的组件)
  • 这是因为在你的渲染方法中调用了contact 并改变了组件的状态。您应该将联系人作为道具传递,并且只在渲染方法中显示它们
  • @Baboo_ 你能在答案中提供一个例子吗?

标签: javascript reactjs typescript react-native react-hooks


【解决方案1】:

尝试在 componentDidMount 方法或 useEffect 中获取 contacts(在您的情况下使用钩子)并将结果存储在使用 useState 的状态中。

  const [contacts, setContacts] = React.useState(null);

  [...]

  React.useEffect(() => {
    // Your function to fetch/get contacts
    const data = contacts();
    setContacts(data);
  }, [])

  [...]

  return (
    <SafeAreaView style={{ flex: 1 }}>
      [...]
      {contacts && contacts.map(contact => (<View>{contact.name}</View>)}
      [...]
    </SafeAreaView>
  );

希望对你有帮助。

【讨论】:

  • 我尝试了您的方法(暂时没有您在退货中所做的事情)。它给了我一个无效的钩子调用错误。更新了代码
  • useEffect 上的无效挂钩调用错误?你有更多细节吗?
猜你喜欢
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 2021-03-24
  • 2022-01-04
  • 2021-11-18
  • 1970-01-01
相关资源
最近更新 更多