1
0

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 1 year has passed since last update.

【React】list要素のkeyにindexを指定してしまい痛い目を見た話

Posted at

list要素のkeyにうっかりindexを指定してしまい、実務でハマったので教訓をまとめておきます。
「listのkeyなんてレンダリングを最適化してくれるだけでしょ?」と甘く考えていたところ、痛い目に会いました。

結論(今回の教訓)

list要素の"key"にはデータの主キー等の"ユニーク"かつ"不変"な値を設定すること!

参考:なぜ"ユニーク"かつ"不変"な値を設定する必要があるのか

reactがkeyの値で同一コンポーネントかどうかを識別しているため。

いろいろな方がまとめられているため、詳細はそちらを確認ください。
簡単に言うと、reactはkeyの値を元に要素の追加、変更、削除を追尾するため、keyにユニークな値を設定することで不要な再レンダリングを防ぐことができます。
また意図せずにindexを指定すると、↓のように思わぬバグに遭遇する可能性があります。

実務でハマった内容

バグが発生した機能
受注した契約情報の一覧ページ

<詳細>
・1ページあたり10件の契約を表示。
・各行に編集ボタンがある。
・編集ボタンを押下すると、その契約の受注金額を一覧上で編集できる。(ReactHookFormにより編集を実現)

かなり雑ですが、↓こんな感じのイメージです。
cost_edit_table1.png

「料金編集」を押すと、その行の料金が一覧上で編集できるようになります。
cost_edit_table2.png

バグの概要
2頁目1行目の契約の編集ボタンを押下すると、1頁目1行目の契約の金額が表示される。

原因
list要素のkeyに配列のindexを指定していたため、2頁目1行目(key=1)が1頁目1行目(同じくkey=1)を参照していた。

表示中の頁が何頁目であれ配列のindexは常に1~10。
そのためkeyindexを指定すると、1頁目1行目、2頁目1行目共にkey=1となる。
1頁目の表示時には、1行目の金額編集フォーム(RHFのdefaultValues)に1頁目1行目の契約の金額が正しく紐づけられる。
しかし2頁目に切り替えても、1行目はkey=1であるためreactから既存の要素と認識されてしまい、要素の新規作成(defaultValuesの設定)が行われず、1頁目1行目の金額を参照するままとなってしまった。

対応内容
keyに契約情報の主キーを設定。
これによりページ切り替え時に各行が新規追加の要素として認識され、フォーム(defaultValues)に対応する契約の金額が正しく設定されるようになった。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?