Lifting State Up
0/3 in this phase0/36 across the roadmap
📖 Concept
In React, data flows down. But what if two sibling components need to share the same data? You "lift" that state up to their closest common ancestor.
The Pattern:
- Move the state from the children to the parent.
- Pass the state down as props to the children.
- Pass "callback functions" (setters) down as props so children can request state changes.
Why do this?
- Single Source of Truth: Ensures all components are in sync.
- Predictability: You know exactly where the data lives and how it's changed.
- Consistency: Avoids "split" state where two components think the value is different.
💻 Code Example
code
1import React, { useState } from 'react';23// 1. Child component that accepts data and a callback4const TemperatureInput = ({ scale, temperature, onTemperatureChange }) => {5 return (6 <fieldset className="border p-4 rounded">7 <legend className="font-semibold px-2">Enter temperature in {scale}:</legend>8 <input9 className="border p-2 w-full mt-2"10 value={temperature}11 onChange={(e) => onTemperatureChange(e.target.value)}12 />13 </fieldset>14 );15};1617// 2. Parent component that "owns" the state18function Calculator() {19 const [temp, setTemp] = useState('');20 const [scale, setScale] = useState('c');2122 const handleCelsiusChange = (value) => {23 setTemp(value);24 setScale('c');25 };2627 const handleFahrenheitChange = (value) => {28 setTemp(value);29 setScale('f');30 };3132 const celsius = scale === 'f' ? (temp - 32) * 5 / 9 : temp;33 const fahrenheit = scale === 'c' ? (temp * 9 / 5) + 32 : temp;3435 return (36 <div className="p-10 max-w-xl mx-auto space-y-4">37 <h2 className="text-2xl font-bold">Temperature Converter</h2>3839 <div className="grid grid-cols-2 gap-4">40 <TemperatureInput41 scale="Celsius"42 temperature={celsius}43 onTemperatureChange={handleCelsiusChange}44 />45 <TemperatureInput46 scale="Fahrenheit"47 temperature={fahrenheit}48 onTemperatureChange={handleFahrenheitChange}49 />50 </div>5152 <div className="mt-4 p-4 bg-yellow-50 rounded border border-yellow-200">53 {celsius >= 100 ? (54 <p className="text-orange-600 font-bold">The water would boil! 🔥</p>55 ) : (56 <p className="text-blue-600">The water would not boil. 💧</p>57 )}58 </div>59 </div>60 );61}6263export default Calculator;
🏋️ Practice Exercise
- Create a 'Login' form where the 'Email' and 'Password' components are separate, but the 'Submit' button in the parent knows both values.
- Build a search interface where one component has the 'Search Input' and another displays the 'Filtered List'.
- Implement a 'Multi-step Form' where state is lifted to the parent to keep track of progress across steps.
- Experiment with lifting state "too high" and notice how it causes unnecessary re-renders in unrelated components.
⚠️ Common Mistakes
Lifting state too high (lifting it to App when only two small components need it).
Duplicating state (keeping a copy in the parent AND the child).
Passing too many props instead of grouping them into an object.
💼 Interview Questions
🎤 Mock Interview
Practice a live interview for Lifting State Up
Was this topic helpful?