各 state を最も近い共通の祖先に置くことで、重複させることなく複数のコンポーネント間でデータを共有します。
このレッスンを Kodokon で開く2 つの兄弟コンポーネントが同じデータを表示する必要があります。例えば、検索フィールドとそれがフィルタリングするリストです。それぞれのローカル state では機能しません。互いに見ることができないからです。解決策は、state を引き上げること、つまり最も近い共通の祖先へ移すことです。親がデータを所有し、props を通じて下へ渡します。
import { useState } from "react";
function ProductPage({ products }) {
const [query, setQuery] = useState("");
return (
<>
<SearchBar query={query} onChange={setQuery} />
<ProductList products={products} query={query} />
</>
);
}すると子は制御されたコンポーネントになります。値を読み取り専用で受け取り、それを変更するには親が提供するコールバック関数を呼び出します。データは props を通じて下へ流れ、変更の要求は関数を通じて上へ流れます。この一方向の流れが、アプリケーションの振る舞いを追いやすくします。
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>
);
}すべてのデータは唯一の信頼できる情報源を持たなければなりません。2 つのコンポーネントがそれぞれ同じ state の自分用のコピーを保存していると、コピーはいずれ食い違います。一方は更新され、もう一方はされず、インターフェイスが一貫しなくなります。state を引き上げれば、そのリスクは取り除かれます。データが多くの階層をまたがなければならない場合、コンポジション(次のレッスン)、そして context が props の受け渡しを軽くします。