UseMemo vs. useEffect + useState
React: useEffect vs useMemo vs useState, which and when use them?

Search for a command to run...
React: useEffect vs useMemo vs useState, which and when use them?

No comments yet. Be the first to comment.
Will be put focus on React UI library, other libraries used together such but not limited to React Query, Redux, Redux Toolkit(RTK)
Avoid the mistake that many do : using useMemo() for retrive data from some long running APIs
Why Does useContext Trigger Unnecessary Re-Renders?
A Comprehensive Comparison for Modern Web Development

Have you ever found yourself thinking in a complex project asking this question, then in this article I will try to answer with examples Let's say the following type is defined: interface Shape { color: string; } Now, maybe we need a way to abstra...

Avoid Object is possibly 'null'.ts(2531)

Typescript generic type parameters: T vs T extends {}

If you are learning hooks probably this question hasn't come across to you yet.
On the other hand I have seen even experienced developers and software engineers not aware of which hook use especially when it came with those that are quite similar and then they end up write always the same function / hooks because it seemed to them the other solutions are "useless"
But if you are more experience you know that for the right job you need the right tool, and thus applies also to use the right hook for the right use cases.
But let's start with code, that I will also recall in a sandbox for more details or for runtime examples.
For example let's consider a simple counter:
// we need also the useState hook in order to store the state of
// the counter variable(result) and increment it with the
// asyncronous function of the hook destructuring ( setResult )
import { expensiveCalculation } from "foo";
function useCalculate(someNumber: number): number {
const [result, setResult] = useState<number>(null);
useEffect(() => {
setResult(expensiveCalculation(someNumber));
}, [someNumber]);
return result;
}
import { expensiveCalculation } from "foo";
function useCalculateWithMemo(someNumber: number): number {
return useMemo(() => {
return expensiveCalculation(someNumber);
}, [someNumber]);
};
Here the sandox to see it live.
They both calculate the count but if you have run the sandbox you can notice that the case with useEffect has a little text showing for few millisecond and the disappearing.
This is because Effect( let's call it in a kind of short way) does run just after the DOM is rendered by React, instead Memo its run immediately does in this case is way much faster.
Well as you may guess the answer is not, though I have seen some PR where engineers where basically using it everywhere.
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.
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 :
The useEffect version runs,
you should consider useMemo as pure optimization technique. Your program should continue to work correctly even if you replace useMemo with regular function call.
useEffect called after component has been rendered, so you can access DOM from it. For example, this is important if you want to access DOM elements via refs.
useEffect guarantees that it will not be fired if dependencies have not changed. useMemo does not give such guarantees.
As stated in the React documentation, you should consider useMemo as pure optimization technique. Your program should continue to work correctly even if you replace useMemo with regular function call.
useEffect + useState can be used to control updates. Even to break-up circular dependencies and prevent infinite update loops.
Also, why is not recommended to use always useMemo is that as the React API docs mention, useMemo doesn’t guarantee that the memoized function won’t be executed again if the dependencies don’t change because React may, in the future, discard cache to improve performance. So if the memoized function has side effects of some kind, it might be smarter to use a custom hook.
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, in this specific case.
It doesn't introduce unnecessary mutable state(this is the advantage that of course is a downside when you need to mutate state properly) and has fewer moving parts.
So you're better off just using useMemo here.
Let's try to answer, as stated in the React docs
In general one should avoid to useMemo() when side effects are involved. At this point one is tempted to think that is an easy thing, but I can guarantee that in real case, is not, for example, what about retrieve some APIs, aren't they a side effect, and what use to handle them especially if they could take long and are update on regular basis, you may read Asynchronous calls in React to get a deep answer but in general, useMemo() is not at all the best option to handle them and anything that happens outside the component where it used, as indeed everything outside the Component is a side effect.