Back to blog

The Illusion of State: Why Your React App is Choking on Context

2 min read

As frontend engineers move from senior to principal roles, they often fall into a predictable trap: confusing over-architecture with good architecture.

You look at a perfectly fine component tree and think to yourself, "This needs a global state manager. Actually, let's use Zustand. Wait, no, let's write a custom React Context provider that wraps the entire application just to pass down a user's theme preference."

Stop right there. You are killing your app's performance and dragging your team's velocity into the mud.

The Cost of 'Clever' Engineering

React Context is not a state management tool. I'll say it again: it is a dependency injection mechanism. When you put rapidly changing values (like a search input or a drag-and-drop coordinate) into a global Context provider, you are forcing every single component that consumes any part of that Context to re-render. Every. Single. Keystroke.

Every hour you spend building a hyper-optimized, generic state machine for a dropdown menu to bypass Context re-renders is an hour you aren't delivering business value.

Think about the mental model. Every layer of abstraction makes onboarding new developers harder. If a junior engineer cannot trace where a prop came from in under two minutes, your architecture has already failed.

You are also fighting the framework. React is explicitly designed for top-down, unidirectional data flow. When you fight the framework to force horizontal data sharing everywhere via Thunks or complex atoms, you introduce impossible-to-debug render cycles. The constant churn in how data is accessed makes the codebase incredibly hostile.

When to Actually Optimize

Optimization should hurt before you apply it. We don't implement memoization preemptively.

You should only start optimizing when a single keystroke in an input field lags the main thread for 200ms. Keep your logic and state collocated. State belongs as close to where it is used as physically possible. If only the Sidebar uses the "isExpanded" toggle, it shouldn't be sitting in Redux.

When your bundle size begins to actively deter users on mobile networks, that is the exact moment you look at route-based code-splitting constraints. Not before.

Stop being a perfectionist and start being a pragmatist. A Principal Engineer values simplicity above all else, simply because simplicity is the only thing that actually scales.