React

Verified against Claude Code · 2026-07-17

Decide whether this state needs lifting, context, or an external store

A decision-framework prompt that picks the right home for shared state based on update frequency and consumer spread, instead of defaulting to context for everything.

Claude CodeChatGPTClaude

The prompt

Ready to copy — highlighted parts are example details you can swap.

<role>
You are deciding where a specific piece of state should live in a React app — lifted to a common parent, in Context, or in an external store (Zustand/Jotai/Redux Toolkit) — based on how it's actually used, not by default habit.
</role>

<state>
The current selected rows in a large data table, used for bulk actions.
</state>

<component_tree>
DataTable owns it today; a BulkActionsBar sibling and a SelectionCount badge in a totally separate header component both need to read it.
</component_tree>

<update_frequency>
Changes on every row checkbox click — could be dozens of times per session, but not per keystroke or per frame.
</update_frequency>

<decision_framework>
Walk through in order and stop at the first rule that applies:
1. If only one component and its direct children need this state, lift it to their nearest common parent. Don't reach for Context for a two-level prop pass.
2. If many components across distant branches of the tree need to read it, but it changes rarely (theme, current user, feature flags), Context is appropriate — but split it into its own provider rather than bundling it with frequently-changing state in the same context value.
3. If the state changes frequently (on every keystroke, every scroll, every animation frame) AND is read by components that shouldn't re-render on every change, Context is the wrong tool — every consumer of a context re-renders on every value change regardless of which part of the value it actually uses. Use an external store with selector-based subscriptions instead.
4. If the state needs to persist across route changes, survive a remount, or be read outside the React tree entirely (analytics, a service worker), it belongs in an external store, not component state or Context.
</decision_framework>

<output_format>
1. Which rule applied and why, in one paragraph.
2. The recommended approach with a short code sketch (not a full implementation) showing the shape.
3. What would change your answer — the specific condition that would push this to a different tier if it turned out untrue.
</output_format>
Customize the highlighted detailsoptional — the prompt above already works

Why this works

The re-render mechanic cited in rule 3 is a real, documented React behavior, not folklore: every component that calls useContext on a given context re-renders whenever that context's Provider value changes, regardless of which slice of the value that particular consumer actually reads — there's no built-in selector mechanism, which is exactly why high-frequency state in Context becomes a measurable performance problem while low-frequency state in Context (theme, current user) is genuinely fine. Structuring the answer as an ordered list with an explicit stop condition prevents the most common failure mode for this kind of question: an LLM listing all three options with generic pros and cons and never committing to one for the actual case in front of it. Asking for "what would change your answer" forces the recommendation to name its own falsification condition, which turns an architectural opinion into something a reviewer can actually check against reality later.

What you get back

Rule 2 applies: SelectionCount and BulkActionsBar are in distant branches, but the state changes on every checkbox click, not every keystroke or frame — right at the boundary between rule 2 and rule 3. Given dozens of updates per session rather than continuous updates, a scoped SelectionContext (not the app-wide context) is the right fit, provided BulkActionsBar and SelectionCount are the only consumers. const SelectionContext = createContext<{ selected: Set<string>; toggle: (id: string) => void } | null>(null); // Provider wraps only the DataTable + BulkActionsBar + SelectionCount subtree, not the whole app. What would change this: if the table grows to thousands of rows with per-row visual state tied to selection (e.g. every row re-rendering on any selection change becomes visibly janky), move to a Zustand store with a per-row selector instead.

Verified against

Claude Code Sonnet 4.6 · 2026-07-17

ChatGPT GPT-5.1 · 2026-07-29

Changelog

  • 2026-07-17 Initial publish, verified against Claude Code (Sonnet 4.6) and ChatGPT (GPT-5.1).

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All React prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY