9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Reactのkeyを使って、意図的な再レンダーを走らせる

Last updated at Posted at 2020-11-25

「え?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などを用いた複雑な処理を書かなくても意図した制御が可能になる
9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?