0

I am using forceUpdate hook like

export const App = ()=>{
    const forceUpdate1 = useForceUpdate1();
    const forceUpdate2 = useForceUpdate2();

    // ignore usage in effect. As both will be used exactly at same place still shows different result
    useEffect(() => {
        /// some logic
        forceUpdate1();  //not working
        // forceUpdate2();  //working
    },[])

    return <>...</>;

}

export const useForceUpdate1 = () => {
    const [counter, setCounter] = React.useState(1);
    return () => {
        setCounter(counter + 1);
    }
}

export const useForceUpdate2 = () => {
    const [_, forceUpdate] = useReducer((x) => x + 1, 0);
    return forceUpdate;
}


Problem

  1. useForceUpdate1() did not re-render.
  2. useForceUpdate2() was working and caused re-rendering.

I think when forceUpdate1 is called multiple times quickly, it will make state changes only once. I mean if counter = 10, then calling force update 2 times sequentially will set counter to 11 and not 12. But counter value is no use to us as state should still trigger a change and <App> should be re rendered.

  1. Is this because of variable capturing?
  2. How to avoid this confusion in future.
amitdigga
  • 6,550
  • 4
  • 26
  • 31
  • Updated code with `dependency array`. – amitdigga Feb 24 '23 at 13:41
  • You need to use setState callback to increment the value in useForceUpdate1, `()=> setCounter((prev) => prev + 1)`. Wrapping the function in useCallback will be better as this function doesn't depends on any external value. – Muhammad Nouman Rafique Feb 24 '23 at 13:48
  • @MuhammadNoumanRafique question is why things are not working as expected. For my app, I will just use `useForceUpdate2` as it is working. – amitdigga Feb 24 '23 at 14:01
  • that's closure. You didn't add`forceUpdate1` in useEffect dependency array and it's still reference to old function where counter is still 0. Whereas useReducer dispatch function or useForceUpdate2 will latest function. You can say dispatch function is just a function that is wrapped in useCallback and it uses setState callback to update state without any external dependency. So forceUpdate1 should be passed in useEffect dependency array but wrapped it inside useCallback and use setState callback to update state otherwise it'll create an infinite loop – Muhammad Nouman Rafique Feb 24 '23 at 15:11

0 Answers0