如何使用条件更新 useState-hook?
How to update a useState-hook with a condition in react?
我在 firebase 中使用反应挂钩(useEffect 和 useState)。
我有一个用户集合,可以毫无问题地从 firebase 获取这些用户。简化的代码如下所示:
const [users, setUsers] = useState([]);
useEffect(() => {
const unsubscribe = database.collection("users").onSnapshot((snapshot) => {
snapshot.forEach((doc) => {
const currentUser = {
id: doc.id,
...doc.data(),
};
setUsers((oldUsers) => [...oldUsers, currentUser]);
});
});
return () => {
unsubscribe();
};
}, []);
到目前为止,还不错。
如果我现在更改用户的一些属性,firebase 会触发并触发 useEffect-hook(这就是我想要的)。
这里的问题: 通过这次触发我的用户数组 (useState) 得到更新并再次推送相同的用户。
我现在想要达到的是这样的:
我只想在我的用户数组中每个用户一次。所以只有新用户应该被添加到这个数组中。我想我需要在 setUsers 方法中进行条件检查。
我想到了这样的事情:
setUsers(
(oldUsers) =>
{
if (oldUsers.indexOf(currentUser) === -1) {
oldUsers.push(currentUser);
}
// HERE I'M NOT SURE WHAT TO DO
// how can I set my users to the updated oldUsers?
// I made some first steps with those approaches...
1) return oldUsers;
2) setUsers(oldUsers);
3) [...oldUsers]
}
);
如代码注释中所述:我如何 update/set 我的用户升级到较新的版本(以防插入新用户)或让用户保持原样(无需再次添加) )?
感谢您的建议!
避免间接改变状态(使用 Array.push
或任何其他方式),它是不一致的。相反 return 如果没有变化则为原始状态,如果有变化则为新对象。例如:
setUsers(oldUsers => {
if (oldUsers.find(user => user.id === currentUser.id))
return oldUsers;
return [...oldUsers, currentUser];
});
在这种特殊情况下,如果没有变化,您可能希望完全避免调用 setUsers
,因为状态本身可用(并且您可以之前检查用户是否存在)。
作为旁注,indexOf
检查在这种情况下不起作用,因为您创建了一个新对象(从您在快照中获得的数据)。这就是为什么它 predicate-based 在我的示例中找到。
我在 firebase 中使用反应挂钩(useEffect 和 useState)。
我有一个用户集合,可以毫无问题地从 firebase 获取这些用户。简化的代码如下所示:
const [users, setUsers] = useState([]);
useEffect(() => {
const unsubscribe = database.collection("users").onSnapshot((snapshot) => {
snapshot.forEach((doc) => {
const currentUser = {
id: doc.id,
...doc.data(),
};
setUsers((oldUsers) => [...oldUsers, currentUser]);
});
});
return () => {
unsubscribe();
};
}, []);
到目前为止,还不错。
如果我现在更改用户的一些属性,firebase 会触发并触发 useEffect-hook(这就是我想要的)。
这里的问题: 通过这次触发我的用户数组 (useState) 得到更新并再次推送相同的用户。
我现在想要达到的是这样的:
我只想在我的用户数组中每个用户一次。所以只有新用户应该被添加到这个数组中。我想我需要在 setUsers 方法中进行条件检查。
我想到了这样的事情:
setUsers(
(oldUsers) =>
{
if (oldUsers.indexOf(currentUser) === -1) {
oldUsers.push(currentUser);
}
// HERE I'M NOT SURE WHAT TO DO
// how can I set my users to the updated oldUsers?
// I made some first steps with those approaches...
1) return oldUsers;
2) setUsers(oldUsers);
3) [...oldUsers]
}
);
如代码注释中所述:我如何 update/set 我的用户升级到较新的版本(以防插入新用户)或让用户保持原样(无需再次添加) )?
感谢您的建议!
避免间接改变状态(使用 Array.push
或任何其他方式),它是不一致的。相反 return 如果没有变化则为原始状态,如果有变化则为新对象。例如:
setUsers(oldUsers => {
if (oldUsers.find(user => user.id === currentUser.id))
return oldUsers;
return [...oldUsers, currentUser];
});
在这种特殊情况下,如果没有变化,您可能希望完全避免调用 setUsers
,因为状态本身可用(并且您可以之前检查用户是否存在)。
作为旁注,indexOf
检查在这种情况下不起作用,因为您创建了一个新对象(从您在快照中获得的数据)。这就是为什么它 predicate-based 在我的示例中找到。