useEffect 不知道状态更新

时间:2021-03-31 17:58:10

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

我在更新 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,不反映映射数组时的更新状态。

1 个答案:

答案 0 :(得分: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 有一个 key 字段,该字段与 dbUser.id 的类型(字符串或整数)相同。