Welcome to the performance module. In this unit, you will identify and fix a common bottleneck in React apps that use Context with a high-frequency loop. Our game dispatches a TICK every second, which can force large parts of the tree to re-render. The root cause is context thrashing: when a context value changes often, every consumer re-renders — even if it only triggers actions and never reads state.
Your goal is to refactor the architecture so that components that only trigger actions no longer re-render on every state update.
We separate read-heavy state from write-only dispatch. The dispatch function from useReducer is a stable reference, so putting it in its own context prevents “write-only” components from re-rendering every second.
Explanation:
- Two contexts: one for state, one for dispatch.
GameDispatchContext.ProviderwrapsGameStateContext.Providerso both are available.- Because
dispatchis stable, components that consume only dispatch won’t re-render onTICK. - Components that read state still re-render as needed when state changes.
These hooks ensure components consume only what they need and fail fast if used outside the provider.
Explanation:
useGameStatereturns the current game state;useGameDispatchreturns dispatch.- Each throws a clear error if called outside
GameProvider. - Components that only need to fire actions should use
useGameDispatchexclusively, avoiding state-driven re-renders.
You profiled the app to spot context thrashing and refactored the architecture by splitting state and dispatch. Now, components that only dispatch actions can remain calm during the 1-second tick storm. Next, you will get hands-on experience and see the re-render count drop as you apply this pattern in practice.
