Reputation: 53
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
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
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