Lift state up
React chapter 141 · Props down, events up · one source of truth · source: react.dev/learn/sharing-state-between-components
The problem
An FAQ accordion should open one answer at a time. Each panel keeps its own isOpen, so panels cannot see each other: you can open all three, and the header cannot tell which one is open.
The pattern that fixes it
Move the state to the closest common parent. The accordion owns activeIndex, passes isActive down, and passes onShow down so a panel can ask for a change. Data flows down, requests flow up, and two-open becomes impossible.
In plain words
Two components that must agree need one shared owner. The parent keeps the value and hands each child a copy, plus a function the child can call to ask for changes.
A single TV remote held by the parent. Kids can ask “switch to channel 2”, but nobody has their own remote fighting over the same TV.
Terms
- props down
- The parent passes values to children. Children read them; they do not change them.
- events up
- The parent also passes callbacks (onShow). A child calls one to ask the parent to change its state.
- single source of truth
- Each piece of state lives in exactly one component. Everyone else derives from it.
Going deeper
Controlled and uncontrolled, again
A panel with its own isOpen is uncontrolled; a panel driven by isActive is controlled. Libraries ship both by letting the parent pass a value or not (chapter 2, useControlled). Lifting state is choosing the controlled shape at the app level.
Lift to the lowest common parent, not the top
Lifting too high makes every keystroke re-render half the app. Put state as low as possible and as high as necessary; move it back down when it is only used in one place (chapter 89), or pass slow parts as children (chapter 90).
When lifting turns into prop drilling
If the common parent is many levels away, pass the value through context, or a store with selectors when updates are frequent (chapters 50, 52, 94). The ownership rule does not change, only the delivery.
Keep learning
- Previous: Identity: position, type, key
- Next: useRef: remember without re-rendering
- Related: Render, then commit
- Related: State is a snapshot
- Related: Effects: sync, then clean up
- Related: Identity: position, type, key
- Related: useRef: remember without re-rendering
More courses
- Jobs, linked to lessons — Browse jobs where every requirement links to the chapter that teaches it. See how ready you are, how long the gap takes to close, and which listings look stale.
- Match a job post to courses — Paste a job post. Each skill is matched to a track here and put in learning order, foundations first.
- Database in depth — How a query becomes work. Indexes, isolation, locks, and the plans that explain why a page is slow — not an ORM tour.
- System Design — Eight interview case studies, from a flash sale and Tatkal to a live final and a chat model, plus JWT in separate chapters.
- Microservices — Microservice patterns one diagram at a time: how to split a monolith, how services talk, and how data stays consistent without distributed transactions.
- Kafka — A beginner-to-senior path through event logs, reliable delivery, production operations, and disaster recovery.
- Frontend system design — How a UI is sliced when it is a product, not a page: ownership of state, cache, routes, and what happens when the network lies.
- CSS in depth — See the box, then the page. Visual chapters from the box model through Flexbox surprises, Grid, selectors, and units, then backgrounds, shapes, and visual effects, each with a playground.
- Accessibility — HTML labs first, then a full pass of WAI-ARIA 1.3: naming, every state, widget and structure roles, live regions, ariaNotify, and relationships.
- Docker — What an image is, why layers cache, and how containers find each other on a network.
- Redis — Fifteen Redis patterns, one picture each: cache, session, lock, counter, rate limiter, queue, and when Redis is the wrong tool.