Search code examples
reactjsreduxreact-reduxmemoization

Is there any reason to memoize Redux action creators in React?


My coworker has stated that articles he's found have pointed to performance increases when memoizing Redux action creators in React, but I've not found anything that supports that and I can't really see how it would help.

Here's an example of what I'm talking about:

const Component = () => {
    const dispatch = useDispatch();
    
    const actions = useMemo(() => ({
        updateField: (...args) => dispatch(updateField(...args)),
        blurField: (...args) => dispatch(blurField(...args)),
        clearAllFields: (...args) => dispatch(clearAllFields(...args)),
    }), [dispatch]);
    
    return (
        <button onClick={actions.clearAllFields}>Clear</button>
    )
}

Does this make sense and I just don't see why? The dispatch function should never change over the course of the component's lifecycle, and neither should the action creators, so there shouldn't be any increase in the number of rerenders whether you memoize the action creators or not.

Note: this is unrelated to the topic of memoizing Redux state.


Solution

  • There's no meaningful point to it, especially in this particular example.

    Yes, strictly speaking, creating a function instance has a non-zero cost, same as i++ has a cost.

    Now, calling useMemo is creating one function instance on every render, and very strictly speaking, creating one instance is cheaper than three instances for updateField/blurField/clearAllFields every time.

    But it's not meaningful enough to be worth worrying about.

    Additionally, there's no benefit in trying to maintain the same function references here. The child element is a <button>; it's not wrapped in React.memo() to avoid re-renders; and there's no further nested child components, so there's no extra cost of React recursing through a deep tree to render it.

    I actually covered some of those points in my post A (Mostly) Complete Guide to React Rendering Behavior.

    So, it's not wrong to call useMemo here, but it's absolutely not necessary, and I really wouldn't bother with it in this case.