Garfield is on board.
Garfield is on board.

Reputation: 53

Is okay to useMemo instead of useEffect for calling side-effect functions

Let's have a Component with take <count: number> props. Inside of that component, I call a side-effect and it should only call when props.count change (1 -> 1 shouldn't count as a change). Is it okay to use useMemo in this way?

  useMemo(() => {
    callAPI();
  }, [count]);

Upvotes: 5

Views: 3535

Answers (2)

Kostiantyn Ko
Kostiantyn Ko

Reputation: 2736

I'd say you could use useMemo for side-effects. It's one of your options if you want to execute some code on prop change BEFORE the first render with the new prop value completes - there might be situations when it's necessary.

The only reason you should not use useMemo is this one small comment in the official React doc:

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.

So instead, you could implement your own hook that fires up before the results of rerender apply to the page. I wrote mine along these lines:

export const usePreEffect = (func: () => void, deps: unknown[]) => {
  const lastDeps = useRef<unknown[]>();
  if (!shallowEqual(deps, lastDeps.current)) {
    func();
  }
  lastDeps.current = deps;
};

and then

  usePreEffect(() => {
    // ...do your specific stuff here, like checking the prev state of the DOM
  }, [prop.value]);

Note, the body of that pre-effect executes in the scope of the render function itself, thus you should NOT be setting state synchronously from there. But you could do a few tricks to make it work, like the use of setTimeout(...).

Upvotes: 5

Utsav Patel
Utsav Patel

Reputation: 2889

No.

You should use useEffect hook for side-effects.

useMemo returns a memoized value.

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

You should not cause any side effect in useMemo.

For more on this you can read here:

https://reactjs.org/docs/hooks-reference.html#usememo

Upvotes: 5

Related Questions