useEffect 依赖导致无限循环

时间:2021-07-19 11:21:38

标签: reactjs firebase

我正在创建一个简单的议程应用程序,该应用程序连接到 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 钩子解决,但我不知道如何解决。 此外,我想为聊天应用程序添加相同的功能(数据将从两侧写入)。是否可以只在两侧之一写入时重新渲染,或者在这种情况下必须无限循环?

2 个答案:

答案 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 挂钩的依赖项。给了我想要的结果。谢谢!