Размещай каждое состояние в ближайшем общем предке, чтобы делиться данными между несколькими компонентами, не дублируя их.
Открыть этот урок в KodokonДва соседних компонента должны показывать одни и те же данные: например, поле поиска и список, который оно фильтрует. Локальное состояние в каждом из них не сработает, потому что они не видят друг друга. Решение - поднять состояние в их ближайшего общего предка: родитель владеет данными и передаёт их обратно вниз через пропсы.
import { useState } from "react";
function ProductPage({ products }) {
const [query, setQuery] = useState("");
return (
<>
<SearchBar query={query} onChange={setQuery} />
<ProductList products={products} query={query} />
</>
);
}Дочерние компоненты становятся тогда контролируемыми: они получают значение только для чтения, а чтобы его изменить, вызывают функцию обратного вызова, переданную родителем. Данные текут вниз через пропсы, запросы на изменение поднимаются вверх через функции. Этот односторонний поток делает поведение приложения лёгким для понимания.
function SearchBar({ query, onChange }) {
return (
<input
value={query}
onChange={(e) => onChange(e.target.value)}
placeholder="Search for a product"
/>
);
}
function ProductList({ products, query }) {
const visible = products.filter((p) =>
p.name.toLowerCase().includes(query.toLowerCase())
);
return (
<ul>
{visible.map((p) => <li key={p.id}>{p.name}</li>)}
</ul>
);
}У каждых данных должен быть единственный источник истины. Если два компонента хранят каждый свою копию одного и того же состояния, копии рано или поздно разойдутся: одна обновится, другая нет, и интерфейс станет несогласованным. Подъём состояния убирает этот риск. Когда данным нужно пройти через много уровней, композиция (следующий урок), а затем контекст облегчают передачу пропсов.