My experience is that useMemo is pretty pointless as a caching mechanism. Where it shines is as an effect dependency manager.
It will be rare that an object’s computation will be so expensive that it makes sense to memoize (barring memoizing entire component trees).
But when you create an object based upon specific inputs, memoizing the result is vital if that result is used as an effect dependency.
Without useMemo, creating
const foo ={ bar: inputProp };
will force an effect dependent on foo to clean up and regenerate on every render. By calling
const foo = useMemo(() => ({ bar: inputProp }), [inputProp]);
the effect dependent on foo only updates when inputProp updates.
That can make a huge difference in perceived performance.
(Apologies for the formatting. Medium’s Android app doesn’t make it easy for me to write code in replies.)