Common React Context Mistakes and Better Patterns

Spot the recurring React context mistakes, from treating it as a global store to recreating the value, and apply the smaller, clearer pattern.

7 min read

Most React context mistakes come from a handful of recurring problems rather than exotic edge cases. Each mistake has a small, repeatable fix. Recognizing it early keeps a context small, explicit, and easy to reason about.

Treating context as a global store

Context passes a value down the tree. It is not a store, and it does not replace local state or props. When every small value lands in context, components stop showing where their data comes from, and every reader re-renders on any change.

The data flow becomes invisible, so the next developer has to hunt for the provider.

Keep state in the component that owns it and pass it down with props when the path is short. Reach for context only when many distant components share the same value. See context vs props for the decision rule.

Recreating the value every render

An inline object or function in the value prop gets a new identity on every render, which re-renders every reader even when the data did not change.

App.jsxApp.jsx
<AuthContext value={{ user, login }}>
  <Page />
</AuthContext>

The provider recreates the object each render, so readers re-render whenever the provider renders, not only when user changes. This is the most common invisible performance leak in context code. Stabilize the value with useMemo and the function with useCallback when measurement shows the re-renders matter, as shown in why context causes re-renders and how to reduce them.

Forgetting the value prop

A provider without a value prop, or with the wrong prop name, behaves as if it received undefined. Readers then receive undefined instead of the default value.

App.jsxApp.jsx
<ThemeContext>
  <Button />
</ThemeContext>

Button reads undefined even when the context was created with a light default. Always pass value, and remember the default only applies when no provider exists at all.

A quick check of the provider's props is usually enough to find this one. See safe default values for React context.

Stuffing many concerns into one context

One context that holds unrelated values forces every reader to re-render when any value changes. A component that only dispatches actions still re-renders with data it never reads.

Split the value from the update function, or split unrelated values into separate contexts, so readers subscribe only to what they use. Components that only dispatch then stop re-rendering with the data they never read.

Mutating the value directly

Mutating the object a provider passes does not update state and hides the change from React. The next render recreates the object anyway, so the mutation is lost.

Keep the value in state and call the setter, so React schedules a render with a fresh value. The mutation never reaches state, so the UI keeps the old value and the bug surfaces only later. If only one component updates the value, pass the setter as a prop instead of publishing it to the whole tree.

Scoping the provider too broadly

A provider that wraps the whole app re-renders every reader below it, even components that only happen to sit in the same tree. A provider for one form or one dashboard section belongs around that section.

Wrap only the part of the tree that reads the value. A theme provider sits at the root, but a provider for a single panel wraps just that panel, so a change wakes only the branch that cares. Scoping also makes each provider's purpose obvious at a glance.

What to learn next

Each mistake links to a dedicated article with the full fix. Start with the one that matches your current symptom, then revisit the others when the same warning signs appear again. The fixes are small, but together they keep a context readable as the app grows.

Rune AI

Rune AI

Key Insights

  • Use context for shared values, not every piece of state.
  • Stabilize the value object so readers do not re-render for nothing.
  • Always pass the value prop on a provider.
  • Split unrelated values so readers subscribe only to what they use.
  • Call the setter instead of mutating the value.
RunePowered by Rune AI

Frequently Asked Questions

Is context a replacement for Redux or Zustand?

No. Context only passes a value down the tree. It has no middleware, DevTools, or fine-grained subscriptions. A state library is a different tool for a different job.

Why do all my readers re-render when I update context?

The provider passes a new value object on each render. Readers re-render whenever the value changes identity, even if the data inside is unchanged.

What is the fastest context mistake to fix?

Forgetting the value prop on the provider. Add value with the intended data, because a provider without it behaves as if it received undefined.

Conclusion

Context mistakes are predictable. Avoid treating context as a global store, keep the value identity stable, always pass the value prop, and split unrelated concerns. Each fix makes the data flow smaller and clearer.