简体   繁体   English

React Hook useEffect 缺少对 useEffect 的依赖

[英]React Hook useEffect has a missing dependency with useEffect

I keep having the error "React Hook useEffect has a missing dependency" I am trying to Save to Local in React and my app is working, but I cannot deploy it because of this warning.我一直遇到错误“React Hook useEffect 缺少依赖项”我正在尝试在 React 中保存到本地并且我的应用程序正在运行,但由于此警告我无法部署它。 The warning is: **React Hook useEffect has a missing dependency: 'saveLocalTodos'.警告是:**React Hook useEffect 缺少依赖项:'saveLocalTodos'。 Either include it or remove the dependency array ** And my code is:要么包含它,要么删除依赖数组 ** 而我的代码是:

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

Just include your dependency in the dependencies array of React.useEffect then.然后将您的依赖项包含在React.useEffect的依赖项数组中。

You're using saveLocalTodos inside your useEffect but not defining it in the dependencies array.您在saveLocalTodos使用saveLocalTodosuseEffect在依赖项数组中定义它。 Normally, the rule of thumb is to include everything (functions, variables, state, props) which is used inside the useEffect to be in the dependencies array.通常,经验法useEffect使用的所有内容(函数、变量、状态、道具)都包含在依赖项数组中。 Because your effect depends on them and should reinvoke itself once their value changes.因为您的效果取决于它们,并且一旦它们的值发生变化就应该重新调用自己。

 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]);

Also, wrap your saveLocalTodods with React.useCallback because, in every re-render of your component, the function reference changes.另外,用React.useCallback包装你的saveLocalTodods ,因为在你的组件的每次重新渲染中,函数引用都会改变。 Then your effect will be fired for no reason.那么你的效果将无缘无故地被触发。 Put todos in the dependencies array inside the saveLocalTodos .todos放在saveLocalTodos内的依赖项数组中。 You want your function to change only when todos change.您希望您的函数仅在待办事项更改时更改。 Otherwise, you will get stale todos.否则,您将获得陈旧的待办事项。

You are getting this error because inside useEffect you're calling getLocalTodos , saveLocalTodos function which are defined outside of useEffect.您收到此错误是因为在useEffect内部,您正在调用在useEffect之外定义的getLocalTodossaveLocalTodos函数。 Ideally inside useEffect dependency array you should define all the outer function, props variable etc. which are used inside useEffect .理想的情况下内部useEffect依赖性阵列应定义所有的功能外,道具可变等,其将在内部使用useEffect So whenever there is any changes in the dependency the effect will be triggered inside useEffect .因此,每当依赖项发生任何变化时,都会在useEffect内部触发效果。 When you are creating any function wrap that function inside React.useCallback and there you can pass dependency of that particular function , just like for your case saveLocalTodos is dependent on todos, so your function will only change when todos will change.当您创建任何函数时,将该函数包装在React.useCallback并且在那里您可以传递该特定函数的依赖项,就像在您的情况下saveLocalTodos依赖于 todos 一样,因此您的函数只会在 todos 更改时更改。 In that way your function will change only when necessary.这样,您的功能只会在必要时更改。

      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]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM