Sharing state lets different parts of your app use the same information. This keeps everything in sync and working together smoothly.
Sharing state between components in React
const [state, setState] = useState(initialValue); // Pass state and setState as props to child components <ChildComponent state={state} setState={setState} />
Use useState hook to create state in a parent component.
Pass both the state and the function to update it (setState) to child components via props.
function Parent() { const [count, setCount] = React.useState(0); return <Child count={count} setCount={setCount} />; } function Child({ count, setCount }) { return <button onClick={() => setCount(count + 1)}>{count}</button>; }
text state with two children: one to update it and one to show it.function Parent() { const [text, setText] = React.useState(''); return ( <> <Input text={text} setText={setText} /> <Display text={text} /> </> ); } function Input({ text, setText }) { return <input value={text} onChange={e => setText(e.target.value)} />; } function Display({ text }) { return <p>You typed: {text}</p>; }
This app shares the color state between a dropdown to pick a color and a text that shows the chosen color in that color. Changing the dropdown updates the text color instantly.
import React, { useState } from 'react'; export default function SharingState() { const [color, setColor] = useState('red'); return ( <main> <h1>Pick a color:</h1> <ColorPicker color={color} setColor={setColor} /> <ColorDisplay color={color} /> </main> ); } function ColorPicker({ color, setColor }) { return ( <select aria-label="Choose color" value={color} onChange={e => setColor(e.target.value)}> <option value="red">Red</option> <option value="green">Green</option> <option value="blue">Blue</option> </select> ); } function ColorDisplay({ color }) { return <p style={{ color: color, fontWeight: 'bold' }}>You selected: {color}</p>; }
Always keep the shared state in the closest common parent of the components that need it.
Passing state and updater as props is simple and works well for small apps.
For bigger apps, consider React Context or state management libraries to share state more easily.
Sharing state means keeping data in one place and letting components use it.
Use useState in a parent and pass state and updater to children via props.
This keeps your app consistent and easier to understand.
Practice
Solution
Step 1: Understand the purpose of shared state
Sharing state means keeping data in one place so multiple components can access and update it.Step 2: Identify the benefit of shared state
This helps keep the app consistent and easier to manage because all components see the same data.Final Answer:
To keep data consistent and allow multiple components to use the same information -> Option AQuick Check:
Sharing state = data consistency [OK]
- Thinking each component should have its own separate state always
- Confusing props with state sharing
- Believing sharing state prevents rendering
Solution
Step 1: Recall how props are passed in JSX
Props are passed as attributes with values, likepropName={value}.Step 2: Identify correct syntax for passing state and updater
The parent passes both state and setState as props:<Child state={state} setState={setState} />.Final Answer:
<Child state={state} setState={setState} /> -> Option BQuick Check:
Props syntax = attribute=value [OK]
- Using children tags incorrectly to pass props
- Passing updater as a child instead of prop
- Missing curly braces around JavaScript expressions
function Parent() {
const [count, setCount] = React.useState(0);
return <Child count={count} setCount={setCount} />;
}
function Child({ count, setCount }) {
return <>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</>;
}Solution
Step 1: Understand initial state and props
The parent sets count to 0 initially and passes count and setCount to Child.Step 2: Analyze button click behavior
Clicking the button calls setCount(count + 1), increasing count by 1 each time.Final Answer:
Count: 0 initially, then increases by 1 each click -> Option CQuick Check:
useState count increments on click [OK]
- Thinking count starts at 1
- Assuming button does not update state
- Confusing setCount usage or scope
function Parent() {
const [value, setValue] = React.useState('');
return <Child value={value} setValue={value} />;
}
function Child({ value, setValue }) {
return <input value={value} onChange={e => setValue(e.target.value)} />;
}Solution
Step 1: Check props passed from Parent
Parent passessetValue={value}instead ofsetValue={setValue}, so setValue is a string, not a function.Step 2: Understand effect on Child component
Child tries to call setValue as a function on input change, but it is a string, causing an error.Final Answer:
setValue prop is passed incorrectly as value instead of the updater function -> Option DQuick Check:
Updater function must be passed, not state value [OK]
- Passing state value instead of updater function
- Ignoring prop names mismatch
- Assuming onChange syntax is wrong
function Parent() {
const [count, setCount] = React.useState(0);
return (
<>
<SiblingA count={count} setCount={setCount} />
<SiblingB count={count} setCount={setCount} />
</>
);
}What is the key reason this works?
Solution
Step 1: Understand state lifting
The parent holds the state and updater, passing them as props to both siblings.Step 2: Explain shared state effect
Because both siblings receive the same state and updater, changes in one update the parent's state, causing both to re-render with the new value.Final Answer:
State is lifted to the common parent and passed down, so both siblings share the same source -> Option AQuick Check:
Lift state up for shared data [OK]
- Thinking siblings can share state without lifting or context
- Believing context API is always required
- Assuming state sync happens automatically without shared source
Ready to prove it?
Pass the test and this pattern moves unknown
