Sharing State
Lift state to a common owner and design controlled components with one source of truth.
When two components must stay synchronized, move their shared state to the closest common parent and pass values and handlers down.
Lift state up
Accordion.tsx
function Accordion() {
const [openId, setOpenId] = useState<string | null>(null);
return sections.map((section) => (
<Panel key={section.id} open={openId === section.id} onOpen={() => setOpenId(section.id)} />
));
}
Panel is controlled because the parent owns its important state. This makes coordination explicit and prevents two panels from disagreeing.
Choose ownership carefully
Keep state local when no sibling or parent needs it. Lift only the state that must coordinate; moving everything to the top creates excessive wiring and broad rerenders.
Keep this
Give each piece of state one owner, lift it to the nearest shared parent, and design controlled component APIs around values and callbacks.
Your place is saved on this device.