| You can get around this identity problem by creating all derived/composed objects via `useMemo`. This ensures that their identity only changes when that of their dependencies do. This lets you get around this "identity problem", but comes with some issues: - Relying on `useMemo` preserved object identity assumes a semantic guarantee, which React docs tell us explicitly not to do [1]. Not providing this guarantee is ridiculous. If their cache is implemented correctly, this should be no problem. - The alternative is to leverage an external lib, which does provide this guarantee [2]. However, it's weird that bringing in an external lib as the more "correct" solution to this incredibly common problem (this is seriously relevant to like 1/2 the components I write) - Wrapping every bit of derived state in a `useMemo` hook is incredibly verbose and annoying, especially when you take dependency arrays into account. I feel like I'm writing generated code. 1. https://reactjs.org/docs/hooks-reference.html#usememo 2. https://github.com/alexreardon/use-memo-one |
One, you don’t rely on a semantic guarantee if you use useMemo for derived state. Avoiding rerendering counts as an optimization as far as the React docs are concerned (your program works if there’s an extra render), and this is in fact exactly what it was intended for. The docs you linked seem to agree: Regardless of whether an offscreen component keeps or doesn’t keep its useMemo, the code is correct and there’s at most one extra render.
Second, while I agree with the verbosity complaint, I personally make a point to use useMemo as coarsely as possible. It’s often completely fine to compute all derived state in a single big lambda that returns one big (immediately destructured) object. It’s only when you have multiple pieces of derived state that update individually and are also all expensive to compute that you actually need fine-grained useMemo calls. And in this case, you can always think about extracting sone of that logic into a helper function/hook.
It’s not perfect, but I think it’s possible to avoid a lot of the pain most of the time.