React: コンポーネントに状態を持たせないのがスタンダード

先日、React を初めて触った時のことを書いた。その後にわかったことをメモ。

www.toyfish.blog

タブを再表示すると消える理由

Semantic UI React でタブを使おうとして、うまくいかなったことを書いていた。

最初、JSX をふつうに書いて、タブの子要素として別のコンポーネントを書いたところ、「タブを切り替えるたびに、タブ内の情報がリセットされる」という結果になりました。

(中略)

Semantic UI React だけでなく Material-UI のタブもアンマウント・マウントを行う、という情報を見かけたので、正当な対処方法が何かあるのだと思いますが、見つけられませんでした。

その後に改めて React の公式サイトを見たら、あろうことかチュートリアルを読んでいなかったことに気づいた。

そのチュートリアルの記載によれば、React では状態を持たせたコンポーネント (uncontrolled component) と、親の状態を反映するだけのコンポーネント (controlled component) を作れるが、後者が標準らしい。

これに従えば、状態を管理しているのはルートのコンポーネントなので、タブやその中のコンポーネントが破棄されようが再生成されようが、情報がリセットされたりしない、ということのようだ。

確かに僕は、ボトムアップコンポーネントを作っていっていて、末端のコンポーネントに状態を持たせてしまっていた。

ただしこの controlled component を作る場合、末端のコンポーネントで状態が変化したら、イベントハンドラを使ってルートコンポーネントに通知し、ルートコンポーネント側で状態 (state) を変更すると、それにしたがって子のコンポーネントにも変更が適用される……という流れを作る必要がある。

チュートリアルには「たかだか数行足すだけだから楽勝でしょ」みたいなことが書いてあるけど、項目数が増えるとその度に数行足すことになる訳で、めんどくさそう。

まだ調べていないけど、それを解決するために出てきたのが Redux ってことなのだろうか。