Avoiding Unnecessary Re-renders
RE · useContextsyntax
// Memoize the value object
const value = useMemo(() => ({ data, handler }), [data]);
// Split read-only data from dispatch
<DataContext.Provider value={data}>
<DispatchContext.Provider value={dispatch}>example
import { createContext, useContext, useMemo, useState } from 'react';
const CountContext = createContext(null);
const CountDispatchContext = createContext(null);
function CountProvider({ children }) {
const [count, setCount] = useState(0);
// dispatch never changes identity
const increment = useMemo(
() => () => setCount(c => c + 1),
[]
);
return (
<CountContext.Provider value={count}>
<CountDispatchContext.Provider value={increment}>
{children}
</CountDispatchContext.Provider>
</CountContext.Provider>
);
}
// Components reading only dispatch won't re-render when count changes
function IncrementButton() {
const increment = useContext(CountDispatchContext);
return <button onClick={increment}>+1</button>;
}Note Splitting context into a data context and a dispatch context is a powerful pattern. Components that only call actions (dispatch) will not re-render when the data changes, because the dispatch reference stays stable.