Real-world mechanisms, state management, edge cases, performance trade-offs, and practical coding.
_currentValue push/pop).dependencies pointing at changed contexts and walks consumers from that provider down — propagation cost scales with consumer count below the provider, not tree size.useContext into small bridge components that pass plain props into memoized heavy children.const AuthStateCtx = createContext<AuthState|null>(null);
const AuthDispatchCtx = createContext<AuthDispatch|null>(null);
function AuthProvider({children}) {
const [state, dispatch] = useReducer(authReducer, null, initFromStorage);
const dispatchStable = useMemo(() => ({
signIn: u => dispatch({type:'signIn', user:u}),
signOut: () => dispatch({type:'signOut'}),
}), []);
return (
<AuthStateCtx.Provider value={state}>
<AuthDispatchCtx.Provider value={dispatchStable}>{children}</AuthDispatchCtx.Provider>
</AuthStateCtx.Provider>
);
}
Points to narrate: stable actions object avoids new identities; state changes re-render only State consumers; persistence handled in effects keyed off state transitions.
Render props expose values as ARGUMENTS: <Auth>{({user}) => ...}</Auth> — explicit dataflow per usage site.
Beats hooks when:
const [value] = useState(() => buildExpensiveTheme());
Lazy initializer runs once per provider mount — not every render. For async bootstrap:
value={} — recreates per render even if discarded.You've completed the 5 free sample questions. Get unrestricted lifetime access to every question, model answer, implementation challenge, and all 27+ technologies for a single payment.
₹399 India / $9 International · One-time settlement · Zero subscription