Reactの勉強をしている中で、
「おぉそうなんだ、知らなかった」みたいな
小ネタを入手したらメモがてらまとめようと思います。
今回は、Reactで同じ位置にあるコンポーネントのStateは
共有されるということを学んだのでメモっておきます!
同じ位置にあるコンポーネントのStateは共有される
以下のサンプルコードでは、Sample
コンポーネント内でtoggle
というStateが管理されています。
このStateによって、表示されるコンポーネントがCount
コンポーネントのA
またはB
に切り替わります。
import { useState } from "react";
const Sample = () => {
const [toggle, setToggle] = useState(true);
const toggleComponent = () => {
setToggle(prev => !prev);
}
return (
<>
<button onClick={toggleComponent}>A/B切り替え</button>
{toggle ? <Count title="A"/> : <Count title="B"/>}
</>
);
};
上記Count
コンポーネントは、title
として受け取った文字列とカウント数を表示し、+
ボタンおよび-
ボタンを押すことでカウントを変更できるようになっています。
const Count = ({ title }) => {
const [count, setCount] = useState(0);
const countUp = () => {
setCount(prevstate => prevstate + 1);
};
const countDown = () => {
setCount(count - 1);
};
return (
<>
<h3>{title}: {count}</h3>
<button onClick={countUp}>+</button>
<button onClick={countDown}>-</button>
</>
);
};
ここで重要なポイントは、Sample
コンポーネント内で
二つのCount
コンポーネントが同じ位置に存在していることです。
この例では、ボタンによりCountコンポーネントのA⇄Bが切り替わりますが、
countの状態はリセットされません。
これは、ReactはあくまでJSXから生成されたUI Treeにおける位置を参照しており、
A/Bの表示が切り替わったとしても、
そのコンポーネントは同じ位置に配置されるので、
同じコンポーネントと見なされるということです。
なかなか、へぇそうなんだ!と驚きでした。
ちなみに、同じ位置、階層になければState共有されないので、
以下のようにdivタグなどを挟んで位置を変えてやれば、
このStateの共有は起きません!
<>
<button onClick={toggleComponent}>A/B切り替え</button>
{toggle ? <Count title="A"/> : <div><Count title="B"/></div>}
</>
まとめ
さて、前述のように
ReactではコンポーネントのStateをその内部で保持するわけではなく、
「この位置にあるコンポーネントの状態はこれだ」というように、
コンポーネントとその状態をUI Treeにおける位置により紐づけます。
- コンポーネントの位置が変わらなければ状態は保持される
- コンポーネントの位置が変われば状態がリセットされる
このような仕組みをきちんと理解することで、効果的にStateを管理し、
コンポーネント間で情報を共有できるようになると思いますので、
是非、皆様もこの概念を理解して、Reactアプリケーションの開発に役立ててください!