Home > Back-end >  How to make functional update of reactjs state object property correctly inside useEffect hook
How to make functional update of reactjs state object property correctly inside useEffect hook

Time:08-20

My initialisation code is given below

const userData = useSelector(state => state.userData); // Obtain from redux state
const [formData, setFormData]    = useState({
                                                userId : '',
                                                name   : '',
                                                email  : ''
                                          });

I want to update userId of formData inside useEffect hook, but I got the following warning in my terminal

React Hook useEffect has a missing dependency: 'formData'. Either include it or remove the dependency array. You can also do a functional update 'setFormData(f => ...)' if you only need 'formData' in the 'setFormData' call

My useEffect code is given below.

useEffect(() => {
    if(userData.userId !== ""){
        setFormData({...formData,userId:userData.userId})
    }
}, [userData]);

If I add dependency formData to useEffect It gives me the error on console as Warning: Maximum update depth exceeded

useEffect(() => {
    if(userData.userId !== ""){
        setFormData({...formData,userId:userData.userId})
    }
}, [userData,formData]);

Please let me know a correct solution for this, Thanks in advance

CodePudding user response:

This is probably the ideal approach:

You can also do a functional update 'setFormData(f => ...)' if you only need 'formData' in the 'setFormData' call

Basically, instead of depending on formData directly, you can change the setFormData call to use whatever the current state is internally:

useEffect(() => {
  if(userData.userId !== ""){
    setFormData(f => ({ ...f, userId: userData.userId }))
  }
}, [userData]);

For all intents and purposes, it will still be the same value of formData. The only difference this makes is that if multiple state updates are queued in a single operation, this callback syntax uses the current state in the batch of updates, rather than the explicit state at the time of render.

For this particular case, it removes the formData variable as a dependency. (Though it may want you to add setFormData to the dependency array, which shouldn't affect anything.)

CodePudding user response:

Just add // eslint-disable-next-line react-hooks/exhaustive-deps to fix the first warning.

useEffect(() => {
    if(userData.userId !== ""){
        setFormData({...formData,userId:userData.userId})
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
}, [userData]);
  • Related