Lifting State Up
Move shared state to the nearest common ancestor and pass both the value and an updater callback as props to keep sibling components in sync.
The Problem: Siblings Need Shared State
Imagine two sibling components that need to share a piece of data — for example, a search input component and a results list that filters based on that search query. If the search state lives inside the search input component, the results list has no way to access it. Neither sibling can see each other's state directly. The solution is to lift the state up to the nearest common ancestor — the parent component that renders both siblings. The parent then passes the state value to one child and the setter callback to the other.
// PROBLEM: SearchInput holds state that ResultsList needs
// but siblings can't communicate directly
function SearchInput() {
const [query, setQuery] = useState(''); // stuck here
return <TextInput value={query} onChangeText={setQuery} />;
}
function ResultsList() {
// How do we access 'query' from the sibling? We can't!
return <FlatList data={/* needs query */} />;
}Lifting State to the Common Ancestor
Move the shared state to the closest common ancestor — the component that renders both siblings. The parent now owns the state and passes it down as props: the search query goes to the results list, and the setter function goes to the search input. The siblings communicate through the parent: the search input calls the setter (passed as a prop), which updates the parent's state, which flows the new query value to the results list as a new prop. This is the fundamental React data flow pattern.
import { useState } from 'react';
import { View, TextInput, Text } from 'react-native';
// Parent owns the shared state
export default function SearchScreen() {
const [query, setQuery] = useState('');
const results = ITEMS.filter(item =>
item.toLowerCase().includes(query.toLowerCase())
);
return (
<View style={{ flex: 1, padding: 16 }}>
<SearchInput query={query} onQueryChange={setQuery} />
<ResultsList results={results} />
</View>
);
}
const ITEMS = ['Apple', 'Banana', 'Blueberry', 'Cherry', 'Avocado'];