React Hook useEffect 缺少对 useEffect 的依赖

React Hook useEffect has a missing dependency with useEffect

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

React Hook useEffect has a missing dependency: 'saveLocalTodos'. Either include it or remove the dependency array

我的代码是:

// 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);
    }
  };

然后将您的依赖项包含在 React.useEffect 的依赖项数组中。

您在 useEffect 中使用了 saveLocalTodos,但没有在 dependencies 数组中定义它。通常,经验法则是将 useEffect 中使用的所有内容(函数、变量、状态、道具)都包含在 dependencies 数组中。因为你的效果取决于它们并且应该在它们的值改变时重新调用它自己。

 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 因为,在你的组件的每个 re-render 中,函数引用都会改变。那么你的效果将无缘无故地被解雇。将 todos 放在 saveLocalTodos 内的 dependencies 数组中。您希望您的功能仅在待办事项更改时更改。否则,您将得到陈旧的待办事项。

您收到此错误是因为在 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]);