「え?keyって無駄なレンダリングが走らない様にするためのものでしょ?」
その通りなのですが、今回は逆に利用する方法を紹介します。
仕組み
- keyは異なるレンダー間でどの子要素が変化しない可能性があるのかについてヒントを出すことができるものである 公式
- 逆に、keyが違う(変わった)のであれば、それは別物として扱われる
利用例1、defaultValueの変更
defaultValueは、非制御コンポーネントの場合に用いる初回のみ設定可能な入力値です。
初回のみなので後から変更することができないのですが、これを変更したいケースがあります。例えばdefaultValueにAPIから取得した値を入れたい場合、具体的には編集フォームで編集元データをfetchしてくるけれど、その前からスケルトンとして入力フォームは見せておきたい場合です。
まずは動かないコードです。
前述の通り、defaultValueは初回のみしか設定できないので、最初に渡された "empty..." のまま変化しません。
See the Pen no_key_defaultValue by ぷーたんは社会人リハビリ中 (@putan) on CodePen.
そこでfetchしたデータを含めた値をkeyに指定します。
これによりInpurFrom
は別物になったと判断して再レンダーされ、defaultValueも再度読み込ませることができるのです。
- <InputForm defaultValue={val} />
+ <InputForm defaultValue={val} key={`input_${val}`} />
See the Pen with_key_defaultValue by ぷーたんは社会人リハビリ中 (@putan) on CodePen.
利用例2、汎用的なリストの切替
非制御だけでなく、制御コンポーネントでも利用ケースが考えられます。
セレクトボックスやラジオボタン、チェックボックスなどのリスト系フォームでリストを切り替えたいケースです。
サンプルとして二段に分かれたラジオボタンを用意しました。
まずは動かないパターンです。
1段階目のメインメニューをパン
に変更してサブメニューが切り替わっても、サブメニューのstateにはごはん
の時の値が保持されているためサブメニューが未選択状態になってしまいます。
See the Pen no_key_radio by ぷーたんは社会人リハビリ中 (@putan) on CodePen.
そこでサブメニューのRadioGroup
にkeyにメインメニューのRadioGroup
の値をkeyとして渡します。
これにより、メインメニューの変更するとサブメニューのRadioGroup
も別物として判断され、local stateも初期化されます。
<RadioGroup
+ key={mainMenu}
name="subMenu"
See the Pen with_key_radio by ぷーたんは社会人リハビリ中 (@putan) on CodePen.
まとめ
- keyを利用してdefaultValueやsetStateの初期値などをリセットする方法を紹介
- うまく使うことでuseEffectなどを用いた複雑な処理を書かなくても意図した制御が可能になる