Lifting State Up Between Siblings0%

Lifting State Up Between Siblings

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

Lifting State Up Between Siblings

1. The Sibling Communication Problem

In React's unidirectional data flow, data flows strictly top-down from parent to child. Sibling components cannot directly communicate with one another or pass state horizontally.

Consider a common scenario:

  • Component A: An AccordionHeader or a SearchInput
  • Component B: An AccordionContent or a SearchResultsList
Output
Parent Container
┌───────┴───────┐
▼ ▼
Component A Component B
(Cannot send data directly across to sibling!)

If Component A holds state in its own local useState, Component B has no way of reading that state or reacting to its changes.

2. The Solution: Lifting State Up

To share state between two or more sibling components:

  1. 1
    Identify the closest common parent component in the tree.
  2. 2
    Move the state up into that common parent.
  3. 3
    Pass the state down to the consuming child as a read-only prop.
  4. 4
    Pass an event handler callback down to the modifying child so it can request state changes in the parent.
Output
Common Parent
[holds state + updater function]
│ │
(passes state) │ │ (passes state & callback)
▼ ▼
Component A Component B

3. Step-by-Step Code Walkthrough

Step 1: Create the Child Components

Child 1 (SearchInput) receives the current search term and a callback:

JSX
export function SearchInput({ query, onQueryChange }) {
return (
<div className="search-box">
<input
type="text"
placeholder="Filter courses..."
value={query}
onChange={(e) => onQueryChange(e.target.value)}
/>
</div>
);
}

Child 2 (SearchResults) receives the filtered list:

JSX
export function SearchResults({ results }) {
if (results.length === 0) {
return <p className="empty-msg">No matching courses found.</p>;
}
 
return (
<ul className="results-list">
{results.map((course) => (
<li key={course.id}>{course.title}</li>
))}
</ul>
);
}

Step 2: Lift State to the Common Parent

The parent component (CourseDirectory) owns the query state and coordinates data flow:

JSX
import React, { useState } from 'react';
import { SearchInput } from './SearchInput';
import { SearchResults } from './SearchResults';
 
const ALL_COURSES = [
{ id: 1, title: 'React.js for Beginners' },
{ id: 2, title: 'JavaScript Mastery' },
{ id: 3, title: 'Django Backend Architecture' }
];
 
export default function CourseDirectory() {
// State lifted to common parent
const [query, setQuery] = useState('');
 
// Derived state: calculate filtered results during render
const filteredCourses = ALL_COURSES.filter((c) =>
c.title.toLowerCase().includes(query.toLowerCase())
);
 
return (
<div className="directory-container">
<h2>MSK Course Search</h2>
{/* Passes state and updater callback to Child 1 */}
<SearchInput query={query} onQueryChange={setQuery} />
{/* Passes derived data to Child 2 */}
<SearchResults results={filteredCourses} />
</div>
);
}

4. Single Source of Truth

Lifting state up establishes a single source of truth. Instead of trying to keep local copies of data synchronized across multiple sibling components, one component acts as the authority. This architectural discipline prevents out-of-sync UI states and simplifies debugging.


Interactive Quiz

Practice Quiz

Question 1
Why can't two sibling components in React share state directly with each other?
Question 2
What is the recommended technique when two sibling components need access to the same state?
Question 3
How does a child component trigger a state update in its parent component?
Question 4
What is the concept of a "Single Source of Truth" in React state architecture?
Question 5
What is "derived state" in the context of lifting state up?
Next Lesson

Handling Synthetic Events in React

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext