Home > Enterprise >  useFocusEffect runs every time useState updates
useFocusEffect runs every time useState updates

Time:04-19

I've been trying to use useState inside useFocusEffect. Following react-navigation I got something like this:

  const [counter, setCounter] = useState(0);

  useFocusEffect(
    useCallback(() => {
      console.log(counter);
    }, [counter]),
  );

Now the problem is that every time counter updates, useFocusEffect fires. What I want is for it to fire only when screen comes into focus. Now I've also tried doing this with navigation focus listener:

  useEffect(() => {
    const onFocus = navigation.addListener('focus', () => {
      console.log(counter);
    });

    return onFocus;
  }, [navigation, counter]);

It works, well partially. While the onFocus function is performed only when screen comes into focus, useEffect fires every time counter updates. Same thing happens when using redux-toolkit slices. How can I prevent this behaviour?


Update

I should add that removing counter from dependency array prevents it from updating in subsequential runs. So I will rephrase the question. Is there a way to either fix useCallback by preventing it from firing every time counter updates or fix useEffect so that it fires only on focus with counter updated?

CodePudding user response:

You included counter in the dependency array of your useEffect. This tells the useEffect to run every time a change is made to counter. See the docs for useEffect here: https://reactjs.org/docs/hooks-reference.html#useeffect

CodePudding user response:

You need to change your useEffect to this:

useEffect(() => {
  const unsubscribe = navigation.addListener('focus', () => {
    console.log(counter);
  });

  return unsubscribe;
}, [navigation]); // remove `counter` from your dependency array

The problem you had was your counter value was in the dependency array of your useEffect dependency array. This means that every time your counter value changes the callback inside your useEffect will run which is obviously undesirable.

You most likely followed CRA's default linting rules where they give you a warning to add items to the dependency array, I'd highly recommend turning that off in your linting rules.

  • Related