Suggest an editImprove this articleRefine the answer for “What does "state lifting" mean?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**State lifting** is moving (lifting) state from a child component up to its parent, so that several components can share common data or stay synchronized with each other. **Key point:** the main goal of state lifting is to have a single "source of truth" for related components, lifting state only as far up as needed, not higher.Shown above the full answer for quick recall.Answer (EN)Image## What is "state lifting" > **State lifting** is moving (lifting) state from a child component up to its parent, > so that several components can **share common data** or **stay synchronized** with each other. --- ### Example problem Imagine we have two input fields: one in Celsius, the other in Fahrenheit. Each holds its own local state. ```javascript function CelsiusInput() { const [celsius, setCelsius] = useState(""); return <input value={celsius} onChange={e => setCelsius(e.target.value)} />; } function FahrenheitInput() { const [fahrenheit, setFahrenheit] = useState(""); return <input value={fahrenheit} onChange={e => setFahrenheit(e.target.value)} />; } ``` The problem: if the user changes Celsius, Fahrenheit will not update. The two components are **not synchronized**, because each has its own state. --- ## The solution - lift the state up (to the parent) Let's move the shared state to the parent component and pass it down to the children via `props`. ```javascript function TemperatureConverter() { const [celsius, setCelsius] = useState(""); const fahrenheit = (celsius * 9) / 5 + 32; return ( <div> <CelsiusInput value={celsius} onChange={setCelsius} /> <FahrenheitDisplay value={fahrenheit} /> </div> ); } function CelsiusInput({ value, onChange }) { return ( <input value={value} onChange={(e) => onChange(e.target.value)} placeholder="°C" /> ); } function FahrenheitDisplay({ value }) { return <p>{value} °F</p>; } ``` Now we have a single **source of truth**, `celsius`, in the parent, and both components are synchronized. --- ## Visually ```javascript Before lifting: [Child1: has state] [Child2: has state] out of sync After lifting: [Parent: has state] ├── [Child1: gets it via props] └── [Child2: gets it via props] synchronized ``` --- ## When state lifting is needed Use "state lifting" when: - several components **depend on the same data**; - one change needs to affect the others; - the state does not "belong" to **just one component**. --- ### Example 1 - a form and a preview ```javascript function App() { const [text, setText] = useState(""); return ( <> <Input value={text} onChange={setText} /> <Preview text={text} /> </> ); } ``` `text` is lifted into `App`, and now `Input` and `Preview` work off the same data. --- ### Example 2 - filtering and a list ```javascript function App() { const [filter, setFilter] = useState(""); const items = ["apple", "banana", "grape"]; const filtered = items.filter(item => item.includes(filter)); return ( <> <Search value={filter} onChange={setFilter} /> <List items={filtered} /> </> ); } ``` Now changing the search field affects the list. If `Search` and `List` each had their own state, they would "live apart". --- ## Difference from state colocation | Concept | Idea | |---|---| | **State colocation** | "Keep state as close as possible to where it is used." | | **State lifting** | "If state is needed by several components, lift it up to where they meet." | It is ideal when these principles are **in balance**: - state is not too high up (to avoid unnecessary re-renders), - but also not too low (to avoid duplicating data). --- ## Mistakes when lifting state | Mistake | Why it's bad | |---|---| | Lifted too high | Triggers a re-render of all child components | | Didn't lift it at all | Data gets duplicated, goes out of sync | | Changing state from a "non-owner" | Breaks the principle of one-way data flow | --- ## Practical pattern If you need to "pass up" a new value from a child component, use a callback (a function from `props`): ```javascript function Child({ onChange }) { return <input onChange={(e) => onChange(e.target.value)} />; } ``` The parent decides what to do with the new value. The child simply "reports the event". --- ## Summary | Question | Answer | |---|---| | What is state lifting? | Moving state from a child component up to the parent | | Why? | So several components can stay synchronized | | How is it implemented? | Via `props` and callbacks | | When is it needed? | When several components depend on the same data | | How does it relate to colocation? | Lift state only as far as needed, not higher | | Main goal | A single "source of truth" for related components | --- ## A simple analogy > Each component is a "room". > > When two devices in different rooms need to work off one remote control, > it makes sense to **move the remote up to the hallway**, > so both can use it.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.