Reactにおける状態のリフトアップ
複数のコンポーネントが同じ変化するデータを反映する必要があることがよくあります。Reactでは、 共通の状態を最も近い共通の祖先コンポーネントに「リフトアップ」することが推奨されています。 例を見てみましょう。
水温計算機を作りたいとします。 これは、ユーザーが温度を入力する入力フィールドと、 判定(水は液体、固体、気体)を表示する段落で構成されます。
この計算機が Calculator というコンテナコンポーネントであるとします:
function Calculator() {
return <div>
</div>;
}
温度を入力するフィールドを TempInp コンポーネントに、
判定を表示する段落を Verdict コンポーネントに分離しましょう:
function Calculator() {
return <div>
<Verdict />
<TempInp />
</div>;
}
TempInp と Verdict の両方が温度の状態を持つ必要があることは簡単に理解できます。
そして、論理的にはこれは同じ温度であるべきです:
入力フィールドにデータが入力されると、判定が表示されなければなりません。
このような場合、状態のリフトアップと呼ばれる手法を使うことが推奨されます: 2つ(またはそれ以上)のコンポーネントで共通する状態は、 それらの共通の親コンポーネントまで「持ち上げ」られます。
今回のケースでは、温度の状態は Calculator コンポーネントに属することになり、
TempInp と Verdict に props として渡されます:
function Calculator() {
const [temp, setTemp] = useState(0);
return <div>
<Verdict temp={temp} />
<TempInp temp={temp} />
</div>;
}
TempInp コンポーネントには温度を変更する入力フィールドが必要です。
しかし、この温度はこのコンポーネントの props であるため、
TempInp 内で直接変更することはできません。
正しくは、Calculator コンポーネントから温度を変更するための特別な関数を渡すことです:
function Calculator() {
const [temp, setTemp] = useState(0);
function changeTemp(event) {
setTemp(event.target.value);
}
return <div>
<Verdict temp={temp} />
<TempInp temp={temp} changeTemp={changeTemp} />
</div>;
}
ちなみに、新しい関数を導入する代わりに、
子コンポーネントに setTemp 関数をそのまま渡すこともできます:
function Calculator() {
const [temp, setTemp] = useState(0);
return <div>
<Verdict temp={temp} />
<TempInp temp={temp} setTemp={setTemp} />
</div>;
}
TempInp と Verdict コンポーネントの実装を書いてください。
状態のリフトアップを使用する必要がある3つのタスクを考えてください。
これらのタスクの解決策を書いてください。