15
votes

I was trying to find a concise answer to this on the web without luck.

Is the following correct regarding the differences between useEffect, useMemo and useState?

  • Both useState and useMemo will remember a value across renders. The difference is that:
    • useMemo does not cause a re-render, while useState does
    • useMemo only runs when its dependencies (if any) have changed, while setSomeState (second array item returned by useState) does not have such a dependency array
  • Both useMemo and useEffect only runs when their dependencies change (if any). The difference is that:
    • useEffect runs after a render happens, while useMemo runs before

Any other key differences I have missed?

2

2 Answers

19
votes

Your points are basically correct, some minor clarification:

useState is causing a re-render on the call of the setState method (second element in the array returned). It does not have any dependencies like useMemo or useEffect.

useMemo only recalculates a value if the elements in its dependency array change (if there are no dependencies - i.e. the array is empty, it will recalculate only once). If the array is left out, it will recalculate on every render. Calling the function does not cause a re-render. Also it runs during the render of the component and not before.

useEffect is called after each render, if elements in its dependency array have changed or the array is left out. If the array is empty, it will only be run once on the initial mount (and unmount if you return a cleanup function).

You can always check Hooks API Reference, which is a pretty solid documentation in my opinion

1
votes
  • The return value of useEffect(callback, [dependency]) is void and It executes after render().
  • The return value of useMemo(callback, [dependency]) is NOT void but memoized value and It executes DURING render().

useEffect() can give same optimization as of useMemo() under the following circumstances:

  • The state variable used in the expensive computation(ie count1) is the only dependency of the useEffect.
  • When we don't mind storing the expensively computed value in state variable.
const [count1, setCount1] = useState(0);
const [expensiveValue, setExpensiveValue] = useState(null);
useEffect(() => {
    console.log("I am performing expensive computation");
    setExpensiveValue(((count1 * 1000) % 12.4) * 51000 - 4000);
  }, [count1]);   
  • Only difference is, useEffect() makes the expensively computed value available after render() while useMemo() makes the value available during the render().
  • Most of the time it does not matter because if that value has been calculated for rendering in the UI, useEffect() and useMemo() both will make the value availble before browser finishes painting.