简体   繁体   English

反应中的“React Hook useEffect 缺少依赖项”

[英]'React Hook useEffect has missing dependencies' in react

I've seen similar issues on this site, but I didn't understood properly why it occurs.我在这个网站上看到过类似的问题,但我没有正确理解它发生的原因。

What I'm facing, is that I'm trying to make a Todo List with React.我面临的是,我正在尝试使用 React 制作待办事项列表。 It's my first time using and building a project with react, so I'm still learning.这是我第一次使用和构建一个带有 React 的项目,所以我还在学习中。

So, what I want to do, is when a user clicks on a button, a modal opens, then it collects the title and the details of that todo, the user clicks save and the modal closes, then a card is displayed displaying that todo.所以,我想做的是,当用户点击一个按钮时,一个模式打开,然后它收集标题和待办事项的详细信息,用户点击保存并关闭模式,然后显示一张卡片显示该待办事项.

Code:代码:

let firstRender = useRef(true);
useEffect(()=> {
    if(firstRender.current) {
        firstRender.current = false;
    }
    else{
        if(!modalState) {
            if(!modalCancel) {
                let Title = todoTitle;
                let Detail = todoDetail;
                setTodo([...todo, {
                    title: Title.toUpperCase(),
                    detail: Detail
                }])
            }

        }
        
    }
}, [modalState, modalCancel])

The modalState is just a state that tells if the modal is open or closed and the modalCancel is a state which tells if the modal is saved or cancelled. modalState只是一个 state,它告诉模态是打开还是关闭,而modalCancel是一个 state,它告诉模态是保存还是取消。 I have some other states as well which are responsible for getting the details and title of the todo from the modal, and a state which keeps track of all the todos.我还有其他一些状态,它们负责从模态中获取待办事项的详细信息和标题,以及一个 state 来跟踪所有待办事项。

This works fine but displays the following warning in the terminal:这工作正常,但在终端中显示以下警告:

React Hook useEffect has missing dependencies: 'todo', 'todoDetail', and 'todoTitle'. Either include them or remove the dependency array. You can also do a functional update 'setTodo(t => ...)' if you only need 'todo' in the 'setTodo' call  react-hooks/exhaustive-deps

If I add all of the states, my app does not work, and I don't want to remove the two dependencies because I want to fire re-render everytime (except the first when the page loads) when the modal closes.如果我添加所有状态,我的应用程序将无法运行,并且我不想删除这两个依赖项,因为我想在模式关闭时每次(除了第一次加载页面时)重新渲染。 Can anyone help me with that?任何人都可以帮我吗? I can show how the all states are written if needed.如果需要,我可以展示所有状态是如何编写的。

your useEffect will re-run when its dependencies change.您的 useEffect 将在其依赖项更改时重新运行。 if you don't put todo as a dependency, when todo change, it won't take new todo value and still use the old value (when it re-run in your case when modalState or modalClose change).如果您不将待办事项作为依赖项,则当待办事项更改时,它不会采用新的待办事项值并仍然使用旧值(当 modalState 或 modalClose 更改时它在您的情况下重新运行)。

ex: when you modalState , your todo is [{title: 'one', detail: 'number one'}] then you execute some other function that change the value of todo state (ex: fetching data from server) and the new todo is now:例如:当您modalState时,您的待办事项是[{title: 'one', detail: 'number one'}]然后您执行其他一些 function 更改待办事项 state 的值(例如:从服务器获取数据)和新的待办事项就是现在:

[
  {title: 'one', detail: 'number one'},
  {title: 'two', detail: 'number two'}
]

but your modalState not change!但是你的 modalState 没有改变! which mean the value of state todo in your useEffect function is not changed!这意味着 state todo在你的 useEffect function 中的值没有改变! ( [{title: 'one', detail: 'number one'}] ) ( [{title: 'one', detail: 'number one'}] )

then you call setTodo inside of useEffect with {title: "three", detail: "number three"} will result:然后你在 useEffect 中用{title: "three", detail: "number three"}调用 setTodo 会得到:

[
  {title: 'one', detail: 'number one'},
  {title: 'three', detail: 'number three'}
]

instead of:代替:

[
  {title: 'one', detail: 'number one'},
  {title: 'two', detail: 'number two'},
  {title: 'three', detail: 'number three'}
]

If you put todo as a dependencies and call setTodo inside of useEffect.如果你把 todo 作为依赖,在 useEffect 里面调用 setTodo。 It will cause infinite loop.会造成死循环。

My Solution:我的解决方案:

when try to update state using useState hook, you can pass a callback instead of just a value.当尝试使用 useState 挂钩更新 state 时,您可以传递一个回调而不仅仅是一个值。 That callback have a prop that is previous value of todo.该回调有一个 prop 是 todo 的先前值。 So now you not using the todo state in your useEffect but you still have todo's value.所以现在你没有在你的 useEffect 中使用 todo state 但你仍然有 todo 的值。 and by "not using state in useEffect" you won't have to pass todo as a dependency.并且通过“不在 useEffect 中使用 state”,您不必将todo作为依赖项传递。

let firstRender = useRef(true);
useEffect(()=> {
    if(firstRender.current) {
        firstRender.current = false;
    }
    else{
        if(!modalState) {
            if(!modalCancel) {
                let Title = todoTitle;
                let Detail = todoDetail;
                setTodo(prevTodo => [...prevTodo, {
                    title: Title.toUpperCase(),
                    detail: Detail
                }])
            }

        }
        
    }
}, [modalState, modalCancel, todoTitle, todoDetail])

wish this help you.希望这对你有帮助。

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

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