React
Lifting State Up
Share data between React components by moving state to their common parent component.
State management becomes tricky when multiple components need the same data. Imagine two dashboard widgets both showing user count — but stored in different places. They'd show different numbers. React solves this with "lifting state up." You move shared state to the nearest common parent component. Then pass it down as props. Both child components stay synchronized. Think of it like a filing cabinet. Instead of keeping duplicate files at two desks, you store the original in one central location. Everyone references the same source.Understanding the Problem
The DataFlow team faces a common scenario. Their stats bar shows total users. Their data table also displays user information. Both components track user counts independently:// Problem: Two components with separate state
function StatsCard() {
const [userCount, setUserCount] = useState(1247);
return (
<div style={{padding: '20px', background: '#f0f9ff'}}>
<h3>Total Users</h3>
<p>{userCount}</p>
</div>
);
}
function UserTable() {
const [users, setUsers] = useState(['Alice', 'Bob']);
return (
<div>
<p>Users: {users.length}</p>
{users.map(user => <div key={user}>{user}</div>)}
</div>
);
}What just happened?
The stats card shows 1247 users but the table shows 2 users. They're completely disconnected. When new users join, only one component would update.
The Lifting Pattern
Here's how lifting state up works. You identify the lowest common ancestor of components that need shared data. Move the state there. Pass it down as props.Implementing the Solution
Time to lift the state up. Move user data to the parent Dashboard component. Pass what each child needs through props:// Solution: Lift state to common parent
function Dashboard() {
const [users, setUsers] = useState([
'Alice Johnson', 'Bob Smith', 'Carol Davis'
]);
return (
<div>
<StatsCard userCount={users.length} />
<UserTable users={users} setUsers={setUsers} />
</div>
);
}userCount. The UserTable gets the full users array.
Handling State Updates
But what happens when child components need to modify the shared state? They can't callsetUsers directly — it doesn't exist in their scope.
The solution: pass down handler functions. Parent component creates functions that modify state. Children call these functions when they need updates:
function Dashboard() {
const [users, setUsers] = useState(['Alice', 'Bob', 'Carol']);
const addUser = (name) => {
setUsers([...users, name]);
};
const removeUser = (name) => {
setUsers(users.filter(user => user !== name));
};
return (
<div>
<StatsCard userCount={users.length} />
<UserTable users={users} onRemove={removeUser} />
<AddUserForm onAdd={addUser} />
</div>
);
}What just happened?
Add or remove users and watch the stats card update automatically. All components stay synchronized because they share the same state source. Try this: Add "David" then remove "Alice" — the count updates instantly.
Common Patterns and Best Practices
Several patterns emerge when lifting state. Here are the most important ones for DataFlow development:Lift to Common Parent
Find the lowest component that contains all children needing shared state.
Pass Handlers Down
Create update functions in parent. Pass them as props to children that need to modify state.
Keep Components Pure
Child components become predictable. Same props always produce same output.
Name Props Clearly
Use descriptive names like onUserAdd or onFilterChange instead of generic onChange.
Common Mistake
Don't lift state too high. If only two sibling components need data, lift to their immediate parent. Lifting to the app root creates unnecessary prop drilling and hurts performance.
Advanced State Lifting
Sometimes you need to lift multiple pieces of related state. DataFlow's filter bar affects several dashboard sections. Instead of separate props for each filter, group them into a single state object:function DataFlowDashboard() {
const [filters, setFilters] = useState({
dateRange: 'last-30-days',
category: 'all',
searchTerm: ''
});
const updateFilter = (key, value) => {
setFilters(prev => ({ ...prev, [key]: value }));
};
return (
<div>
<FilterBar filters={filters} onFilterChange={updateFilter} />
<StatsCards filters={filters} />
<DataTable filters={filters} />
</div>
);
}What just happened?
Change any filter and watch all dashboard sections update together. The date range affects revenue stats. Category selection updates user counts. Search terms filter across all components.
When to Use Context Instead
If you're passing the same props through many component levels, consider React Context. Context provides a way to share data without manually passing props through every level. Great for themes, user authentication, or global settings.
Quiz
1. You have two DataFlow components that both need user data: StatsCard shows user count, UserList shows user names. They currently have separate user state. What's the best way to synchronize them?
2. A DataFlow child component needs to modify state that lives in its parent component. How should the child trigger state updates?
3. When lifting state up in a DataFlow dashboard, where should you place the shared state?
Performance Optimization
DataFlow handles thousands of transactions. Learn React performance techniques to keep your dashboard fast and responsive under heavy data loads.