4 ms·
In many cases, we can use useMemo instead of useEffect: - the function is run immediately (during the render cycle, not after) - we can take advantage of the
by karaokeyoga 4y ago
In many cases, we can use useMemo instead of useEffect:
- the function is run immediately (during the render cycle, not after)
- we can take advantage of the dependency array
I think the reason this pattern isn't more popular is that we're taught to use useMemo to memoize a result, but we can also use it more simply … to run a function (during the render cycle) whenever the dependency array changes.
Just call useMemo and don't assign the result to anything, such as:
useMemo(myFunction, [dependency array])
- lukax 4y agouseMemo is really nice for sync effects but it breaks hot reload because hot reload does not call useMemo again. E.g. you can subscribe to something using useMemo (so that it is synchronous and you can use the current subscription value in the current render) and then unsubscribe using useEffect as a cleanup callback. When the component is hot reloaded, the useEffect cleanup callback will be called but the useMemo will not be called again if the dependencies do not change. You can use useSyncExternalStore for that but you need to make sure that your subscription value is immutable or hack around it with refs.
- Rapzid 4y agoThis is underdiscussed IMHO. I refer to the render function calls as "the way down" and then after everything is mounted when React starts calling the useEffect callbacks "the way up". Many applications suffer from the waterfall rendering problem but even for those that don't, if they are large, they will absolutely want to kick off network calls on "the way down". You can easily add a ton of time to LCP by waiting to kick network calls off until the tree has mounted. I actually go a little out of my way to make sure as much of the tree as possible can render and mount with missing data. This way the work is occurring while data is fetching in parallel, and then a minimized number of components need to be updated once the data has arrived.
- mrctte 4y agoIsn't this exactly what useLayoutEffect is for? https://react.dev/reference/react/useLayoutEffect https://react.dev/reference/react/useLayoutEffect
- karaokeyoga 4y agouseLayoutEffect is called after the render cycle but before the “paint”. useMemo is called during the render cycle (i.e. immediately). You can confirm this via console.log: useMemo(() => console.log(1), []) console.log(2) … will print 1 then 2. If you replace useMemo with useLayoutEffect, you’ll get 2 then 1.
- koromak 4y agoThis is smart. I guess because the common wisdom you see repeated everywhere is "Never memoize unless you're sure of the benefits". Never thought about using them for any other purpose.