我正在创建一个简单的议程应用程序,该应用程序连接到 Firebase 作为后端。我想在每次写入时获取数据,并试图避免无限循环。
useEffect(() => {
const getTodos = () => {
console.log("I will run");
db.collection("Users")
.doc(user.email)
.collection("Todos")
.get()
.then((snapshot) => {
const loadedTodos = snapshot.docs.map((docs) => {
return {
todo: docs.data().todo,
isCompleted: docs.data().isCompleted,
id: docs.id,
};
});
setTodos(loadedTodos ?? []);
});
};
getTodos();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [todos]);
初始待办事项状态为空。但是,当我获取 firebase 数据时,它会发生变化,然后导致组件本身重新渲染,从而导致再次获取导致无限循环。由于这个原因,我打破了 firebase 中 spark 计划的限制,并因临时阻塞而浪费了几天的工作。我认为这可以通过 useCallback 钩子解决,但我不知道如何解决。 此外,我想为聊天应用程序添加相同的功能(数据将从两侧写入)。是否可以只在两侧之一写入时重新渲染,或者在这种情况下必须无限循环?
答案 0 :(得分:2)
你想要的效果依赖是 user.email
useEffect(() => {
const getTodos = () => {
console.log("I will run");
db.collection("Users")
.doc(user.email)
.collection("Todos")
.get()
.then((snapshot) => {
const loadedTodos = snapshot.docs.map((docs) => {
return {
todo: docs.data().todo,
isCompleted: docs.data().isCompleted,
id: docs.id,
};
});
setTodos(loadedTodos ?? []);
});
};
getTodos();
}, [user.email]);
您可以将其理解为:每次 user.email
更改时,我都想重新获取待办事项列表。
编辑:正如其他人所说,您观察到无限循环的原因是因为效果本身改变了效果的依赖关系,这会导致效果再次运行。这通常可以通过“提升状态”来解决 - 但在这种情况下,这是因为您使用了错误的依赖项。
答案 1 :(得分:0)
我刚刚添加了一个新的 useState 挂钩,shouldComponentRerender,它会在调用 (addTodos, deleteTodo, setCompletionState) 的函数时发生变化,然后将 shouldComponentRerender 状态添加为 useEffect 挂钩的依赖项。给了我想要的结果。谢谢!