简体   繁体   中英

'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. It's my first time using and building a project with react, so I'm still learning.

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. 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.

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. 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).

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:

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

but your modalState not change! which mean the value of state todo in your useEffect function is not changed! ( [{title: 'one', detail: 'number one'}] )

then you call setTodo inside of useEffect with {title: "three", detail: "number three"} will result:

[
  {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. 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. That callback have a prop that is previous value of todo. So now you not using the todo state in your useEffect but you still have todo's value. and by "not using state in useEffect" you won't have to pass todo as a dependency.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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