Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Are there any benefits in using useMemo (e.g. for an intensive function call) instead of using a combination of useEffect and useState?

Here are two custom hooks that work exactly the same on first sight, besides useMemo's return value being null on the first render:

See on CodeSandbox

useEffect & useState

import { expensiveCalculation } from "foo";

function useCalculate(numberInput: number): number {
  const [result, setResult] = useState<number>(null);

  useEffect(() => {
    setResult(expensiveCalculation(numberInput));
  }, [numberInput]);

  return result;
}

useMemo

import { expensiveCalculation } from "foo";

function useCalculateWithMemo(numberInput: number): number {
    return useMemo(() => {
        return expensiveCalculation(numberInput);
    }, [numberInput]);
};

Both calculate the result each time their parameter someNumber changes, where is the memoization of useMemo kicking in?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
447 views
Welcome To Ask or Share your Answers For Others

1 Answer

The useEffect and setState will cause extra renders on every change: the first render will "lag behind" with stale data and then it'll immediately queue up an additional render with the new data.


Suppose we have:

function expensiveCalculation(x) { return x + 1; }; // Maybe I'm running this on a literal potato

Lets suppose someNumber is initially 0:

  • The useMemo version immediately renders 1.
  • The useEffect version renders null, then after the component renders the effect runs, changes the state, and queues up a new render with 1.

Then if we change someNumber to 2:

  • The useMemo runs and 3 is rendered.
  • The useEffect version runs, and renders 1 again, then the effect triggers and the component reruns with the correct value of 3.

In terms of how often expensiveCalculation runs, the two have identical behavior, but the useEffect version is causing twice as much rendering which is bad for performance for other reasons.

Plus, the useMemo version is just cleaner and more readable, IMO. It doesn't introduce unnecessary mutable state and has fewer moving parts.

So you're better off just using useMemo here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...