Skip to content
Prompt of the Day — Part 24 of 30

Prompt of the Day: Replace Prop Drilling with Proper State Management

Written by claude-sonnet-4 · Edited by claude-sonnet-4
prop-drillingstate-managementzustandreact-contextreacttypescript

Part 24 of 30 in the Prompt of the Day series


Prop drilling happens when you pass data through three, four, five levels of components just to get it to the one component that actually needs it. Every component in between becomes a reluctant courier, accepting props it will never use just to hand them off. The problem is not just aesthetic -- intermediate components re-render when those props change, your component signatures bloat, and a single data shape change forces you to touch half a dozen files. In 2025, state management comparisons consistently show that most teams reach for the wrong solution because they apply it too broadly or not broadly enough. The fix is knowing when to extract state and exactly what to extract it into.


The Prompt

I have a React component tree where props are being drilled through 3 or more levels. Please help me refactor it.

Here is the relevant component tree:
[PASTE YOUR COMPONENTS HERE]

Do the following:
1. Identify every prop that is passed through a component that does not consume it (only forwards it).
2. For each drilled prop, determine the right solution:
   - React Context: if the value changes infrequently and the subtree is self-contained (e.g., theme, locale, current user)
   - Zustand: if the state is shared across unrelated parts of the app, updates frequently, or needs middleware like persistence
   - Jotai: if the state is atomic and fine-grained, each piece updates independently, or you need derived/computed atoms
3. Refactor the component tree to eliminate the drilling using the chosen solution.
4. Preserve all existing TypeScript types and interfaces. Do not widen or loosen any type.
5. Do NOT move props into global state if a component genuinely owns them and passes them to direct children only. Call out which props you are leaving as props and why.
6. Show the before and after for each affected component.

Why It Works

This prompt is specific enough to prevent the AI from making sweeping decisions. The three-level threshold is explicit, so the model does not over-extract props from shallow trees where drilling is perfectly fine. The tiered decision logic -- Context for simple, Zustand for medium complexity, Jotai for atomic state -- matches the decision framework that practitioners use in 2025. Zustand at roughly 1KB gzipped carries almost no bundle cost, and Jotai's per-atom subscriptions mean components only re-render when the atoms they actually use change. The instruction to preserve TypeScript types is critical -- a refactor that silently drops readonly or widens a union type introduces runtime risk. The escape hatch at step 5 is equally important: it tells the AI that not everything is global state, preventing the common mistake of lifting perfectly local props into a shared store.


The Anti-Prompt

Bad version:

Fix my prop drilling.

Why it fails: The AI has no context about your component tree, no signal about how complex your state actually is, and no constraint on TypeScript. You will get a generic Context API example that may not fit your use case, and you will likely end up with a single monolithic context that causes every consumer to re-render on every update -- which is measurably worse performance than splitting by domain or moving to Zustand. Without the "leave genuine props alone" instruction, the AI may also extract props that should stay local, making your components harder to test in isolation.


Variations

Variation 1 -- Force Zustand across the board:

Add to the prompt: "Use Zustand for all refactored state. Create a single store file with typed slices. Use selector functions in every component to subscribe only to the state it needs."

Use this when you have a medium-to-large app with auth, cart, or feature flags that multiple unrelated subtrees need to access. Zustand's store lives outside the React tree, so you can read and update it from utility functions and WebSocket handlers without workarounds.

Variation 2 -- Force React Context with performance guards:

Add to the prompt: "Use React Context only. Split contexts by update frequency -- do not put fast-changing state in the same context as slow-changing state. Wrap context values in useMemo."

Use this when you want zero external dependencies and your state changes infrequently. Splitting contexts by domain reduces the re-render surface the same way component-level memoization does.

Variation 3 -- Jotai for atomic/form state:

Add to the prompt: "Use Jotai atoms. Each independent piece of state should be its own atom. Where one value is derived from another, use a derived atom with the atom(get => ...) pattern. Avoid putting unrelated state in a single atom."

Use this when you have a complex form, a real-time dashboard, or a collaborative UI where different sections update independently at high frequency. Jotai's atomic subscriptions mean a change to one atom does not trigger re-renders in components that use different atoms.


When You Would Actually Use This

You are three weeks into a feature and a new designer asks for a loading spinner in the page header that reflects whether any data fetch is in progress. You trace the isLoading flag up through four components to find it lives in a deeply nested data component. Rather than threading a new prop through the tree, this prompt gets you a Zustand action and a single selector in the header component within one AI pass -- and your intermediate components stay untouched.


Ask The Guild

Have you ever extracted something into global state that you later regretted? What was the prop that should have stayed a prop? Share your story in the thread.

Copy A Prompt Next

Review and debug

If this article changed how you think about the problem, copy a prompt that turns that judgment into one safe, reviewable next step.

Matching public prompts

23

Keep the task scoped, copy the prompt, then inspect one reviewable diff before the agent continues.

Need the safest first move instead? Open the curated sample prompts before you browse the broader library.

Working With AI ToolsWorking With AI Tools

System Prompts — .cursorrules and CLAUDE.md Explained

Write system prompts that give AI persistent context about your project and preferences.

Preview
**Use this when you want the agent to draft your persistent project instructions:**
"Help me write a system prompt file for this project.
Tool target: [Cursor / Claude Code / both]
Project summary: [what the app does]
Stack: [frameworks, languages, key services]
Prompt Engineering

Turn this workflow advice into a durable operating system

Prompt and workflow posts are the quick win. The learning paths turn them into a durable operating model for tools, prompts, and agent supervision.

Best Next Path

Working With AI Tools

Explorer · Free

Turn ad hoc prompting into a repeatable workflow with better tool choice, stronger prompting, and safer day-to-day AI habits.

23 lessonsIncluded in the free Explorer plan

Need the free route first?

Start with Foundations for AI-Assisted Builders if you want the workflow and vocabulary before you dive into the deeper path above.

T

About Tom Hundley

Tom Hundley writes for builders who need stronger technical judgment around AI-assisted software work. The Guild turns production experience into public articles, copy-paste prompts, and structured learning paths that help non-software developers supervise AI agents more safely.

Do this next

Leave this article with one concrete move. Copy the matching prompt, or start with the path that teaches the safest next skill in sequence.