React: useEffect vs useMemo vs useState

All we need is an easy explanation of the problem, so here it is.

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?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

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

Method 2

  • 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.

Method 3

useMemo Used to memoize calculations/values that belong to the component but not necessarily to the component state e.g. validations, methods that rely on component and must return a value;

  const validEmail = React.useMemo(() => validateEmail(email), [email])
  /* Now use 'validEmail' variable across the component, 
     whereas 'useEffect' return value is void and only used for unmounting duties, 
     like unsubscribing from subscription e.g. removeInterval*/

from docs:

Remember that the function passed to useMemo runs during rendering. Don’t do anything there that you wouldn’t normally do while rendering. For example, side effects belong in useEffect, not useMemo.

useEffect Side effects:

Mutations, subscriptions, timers, logging, and
other side effects

setState‘s setTimeout‘s setIntervalref assignments, API calls, or anything that doesn’t perform heavy calculations more belong in here.

Also remember that optimisation comes at a cost, therefore React suggests to use useMemo only when memoization/optimisation is necessary and in other cases rely on useEffect when necessary:

You may rely on useMemo as a performance optimization, not as a semantic guarantee.

In the future, React may choose to “forget” some previously memoized
values and recalculate them on next render, e.g. to free memory for
offscreen components. Write your code so that it still works without
useMemo — and then add it to optimize performance.

[state, setState] = useState() that is to update the given state variable which stays stable during re-renders and calling setState attached to it triggers a re-render. Purpose of this hook is not much relatable to the above two hooks.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply