2

I have the following situation:

  const [values, setValues] = useState({
    username: "",
    password: ""
  });

  const [submitButton, setSubmitButton] = useState({
    disabled: true
  });

 useEffect(() => {
    const disabled = !(values.username.length && values.password.length);

    setSubmitButton({ ...submitButton, disabled });
  }, [values]);

This works perfectly fine and does exactly what I would like but ESLint complains with react-hooks/exhaustive-deps warning.

When I do eslint autofix, it adds setSubmitButton as a dependency to useEffect, however that causes an infinite loop. This seems like such a simple situation but I can't figure out what I'm doing wrong. I've seen code of other people that use setState and the like within useEffect without declaring it as a dependency.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Kerim Güney
  • 1,059
  • 1
  • 10
  • 23

1 Answers1

3

You should use the functional updater form of useState, which will provide a snapshot of your state, thus eliminating the need for directly reference it.

setSubmitButton(previous => ({ ...previous, disabled }));

Since React already knows the current value of submitButton and will only run the callback when changing the state this will happen outside your component's scope and eslint won't be mad at you. In Dan's words

I like to think of these cases as “false dependencies”. Yes, count was a necessary dependency because we wrote setCount(count + 1) inside the effect. However, we only truly needed count to transform it into count + 1 and “send it back” to React. But React already knows the current count. All we needed to tell React is to increment the state — whatever it is right now.

Font

Dupocas
  • 20,285
  • 6
  • 38
  • 56
  • Thank you very much! This is exactly what I needed. – Kerim Güney Dec 11 '19 at 07:50
  • What if i need to directly reference that state? I have a use case where i have to update that state and also update another state based on that state. – chetan Jan 28 '21 at 09:12
  • 1
    this is too vague. Please consider post as a question with a more detailed description of your problem – Dupocas Jan 28 '21 at 13:35