【问题标题】:React Hook useEffect has a missing dependency with useEffectReact Hook useEffect 缺少与 useEffect 的依赖关系
【发布时间】:2021-01-16 18:29:33
【问题描述】:

我正在尝试在 React 中保存到本地,并且我的应用程序正在运行,但由于此警告,我无法部署它。警告是:

React Hook useEffect 缺少一个依赖项:'saveLocalTodos'。 要么包含它,要么移除依赖数组

我的代码是:

// Run once when the app starts
  useEffect(() => {
    getLocalTodos();
  }, []);

  // useEffect
  useEffect(() => {
    // Function
    function filterHandler() {
      switch (status) {
        case `completed`:
          setFilteredTodos(todos.filter((todo) => todo.completed === true));
          break;
        case `uncompleted`:
          setFilteredTodos(todos.filter((todo) => todo.completed === false));
          break;
        default:
          setFilteredTodos(todos);
          break;
      }
    }
    filterHandler();
    saveLocalTodos();
  }, [todos, status]);

  // Save to Local
  const saveLocalTodos = () => {
    localStorage.setItem("todos", JSON.stringify(todos));
  };
  const getLocalTodos = () => {
    if (localStorage.getItem("todos") === null) {
      localStorage.setItem("todos", JSON.stringify([]));
    } else {
      let todoLocal = JSON.parse(localStorage.getItem(`todos`));
      setTodos(todoLocal);
    }
  };

【问题讨论】:

标签: javascript reactjs use-effect


【解决方案1】:

只需将您的依赖项包含在 React.useEffect 的依赖项数组中即可。

您在 useEffect 中使用了 saveLocalTodos,但未在依赖项数组中定义它。通常,经验法则是将 useEffect 中使用的所有内容(函数、变量、状态、道具)包含在依赖项数组中。因为您的效果取决于它们,并且一旦它们的值发生变化就应该重新调用自己。

 const saveLocalTodos = React.useCallback(() => {
    localStorage.setItem("todos", JSON.stringify(todos));
  }, [todos]);

  useEffect(() => {
    // Function
    function filterHandler() {
      switch (status) {
        case `completed`:
          setFilteredTodos(todos.filter((todo) => todo.completed === true));
          break;
        case `uncompleted`:
          setFilteredTodos(todos.filter((todo) => todo.completed === false));
          break;
        default:
          setFilteredTodos(todos);
          break;
      }
    }
    filterHandler();
    saveLocalTodos();
  }, [todos, status, saveLocalTodos]);

另外,用React.useCallback 包裹你的saveLocalTodods,因为在每次重新渲染组件时,函数引用都会发生变化。然后你的效果将无缘无故地被解雇。将todos 放入saveLocalTodos 内的依赖项数组中。您希望您的函数仅在待办事项更改时更改。否则,你会得到陈旧的待办事项。

【讨论】:

  • 感谢您的回答!我已经尝试过了,现在我遇到了一个错误:在定义之前使用了 saveLocalTodos' ??‍♀️
  • 您认为现在错误的原因是什么?它实际上写在您的错误消息中。在使用之前定义你的函数。我现在更新了代码。检查一下。
  • OMG??‍♀️ 一直坐到凌晨 1 点才想弄清楚,现在我的大脑无法运作。非常感谢!
  • 欢迎编程!
  • 哈哈是的,你可以说我是新手!
【解决方案2】:

您收到此错误是因为在 useEffect 内部您正在调用在 useEffect 之外定义的 getLocalTodossaveLocalTodos 函数。理想情况下,在 useEffect 依赖数组中,您应该定义在 useEffect 中使用的所有外部函数、props 变量等。因此,每当依赖项发生任何变化时,都会在useEffect 内触发效果。当您创建任何函数时,将该函数包装在 React.useCallback 中,在那里您可以传递该特定函数的依赖关系,就像您的情况一样,saveLocalTodos 依赖于 todos,因此您的函数只会在 todos 发生变化时发生变化。这样,您的功能将仅在必要时更改。

      const filterHandler = React.useCallback(() => {
        switch (status) {
            case `completed`:
              setFilteredTodos(todos.filter((todo) => todo.completed === true));
              break;
            case `uncompleted`:
              setFilteredTodos(todos.filter((todo) => todo.completed === false));
              break;
            default:
              setFilteredTodos(todos);
              break;
          }
      }, [todos, status]);
      
      // Save to Local
      const saveLocalTodos = React.useCallback(() => {
        localStorage.setItem("todos", JSON.stringify(todos));
      }, [todos]);
      
      const getLocalTodos = React.useCallback(() => {
        if (localStorage.getItem("todos") === null) {
          localStorage.setItem("todos", JSON.stringify([]));
        } else {
          let todoLocal = JSON.parse(localStorage.getItem(`todos`));
          setTodos(todoLocal);
        }
      },[]);

      useEffect(() => {
        filterHandler();
        saveLocalTodos();
        getLocalTodos();
      }, [getLocalTodos, filterHandler, saveLocalTodos]);

【讨论】:

    猜你喜欢
    • 2021-02-23
    • 2020-10-26
    • 2019-10-24
    • 2020-07-24
    • 2020-03-07
    • 2020-02-25
    • 2020-06-11
    • 2020-03-30
    • 2020-12-29
    相关资源
    最近更新 更多