【问题标题】:useEffect not aware of state updateuseEffect 不知道状态更新
【发布时间】:2021-06-27 18:26:32
【问题描述】:

在 useEffect 中更新状态时,我面临重复元素的问题, 我想做的是从firebase获取数据并遍历数据并使用useState更新数组,如果数组中已经存在该元素,则跳过添加并移至下一个元素。代码如下

import React, {useState, useEffect} from 'react';
import {View, FlatList} from 'react-native';


const Users = props => {
const [users, setUsers] = useState([]);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
  (async () => {
      const dbUsers = await db.collection('users').get();
        if (dbUsers.length !== 0) {
          dbUsers.map((filteredUser) => {
            if (dbUsers.exists) {
             const isUserExists = users.find((u) => u.key === dbUsers.id);
              if (!isUserExists) {
                setUsers((prevState) => [
                 ...prevState,
                 new ContactsList(
                 dbUsers.id,
                 dbUsers.data().name,
                 dbUsers.data().number,
                 dbUsers.data().profileAvtar,
                 dbUsers.data().onesignalId,
                ),
             ]);
            }
          }
        });
      }
})();
}, [users]});

setUsers,映射数组时不反映更新状态。

【问题讨论】:

  • filteredUsers 是在某个地方定义的,还是应该是 users
  • 对不起,我忘了编辑这一行,是的,filteredUsers 应该是用户。
  • 检查 u.key 和 dbUsers.id 是否为相同的数据类型,例如是否都是字符串或数字
  • 这到底是什么:dbUsers.id?您获取一组用户并将其存储在 dbUsers 上,然后将它们映射为过滤用户,那么您指的是哪个 id?据我了解,dbUsers 没有 id...
  • 是的,两者都是字符串,我也得到了 isUserExists = true,但我的问题是 setUsers 被设置了两次,之后我得到了 isUserExists = true;

标签: reactjs firebase react-native react-hooks use-effect


【解决方案1】:

当您想要更新一组值时,总是更喜欢通过一次调用 setUsers 来更新它,而不是使用多次调用一次附加一个值。在您当前的实施中,它返回的每个用户记录都会触发对 db.collection('users').get() 的新调用,从而导致您看到的重复。

试试这个:

const Users = props => {
  const [users, setUsers] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    (async () => {
      const dbUsers = await db.collection('users').get();
      const updatedUsers = dbUsers.map(dbUser => {
        // look for an existing user
        const existingUser = users.find(u => u.key === dbUser.id);

        // if we already have the user locally, don't update
        if (existingUser) {
          return existingUser;
        }

        // otherwise, create and return a new user from the remote data
        return new ContactsList(
          dbUser.id,
          dbUser.data().name,
          dbUser.data().number,
          dbUser.data().profileAvtar,
          dbUser.data().onesignalId,
        );
      });
      setUsers(updatedUsers);
    })();
  }, [users]);
}

正如@lissettdm 指出的那样,确保ContactsList 具有与dbUser.id 相同类型(字符串或整数)的key 字段。

【讨论】:

    猜你喜欢
    • 2021-04-07
    • 2021-10-02
    • 2021-01-19
    • 2021-04-24
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 2022-07-08
    相关资源
    最近更新 更多