2
1

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のkeyについて

Last updated at Posted at 2022-05-08

コンポーネントへのkeyの設定

Reactはいい感じにDOMの更新を行う都合で、動的に複数の子要素を作るときはkeyを割り当てる必要があります。なくても動きますが、ブラウザのコンソールにwarningが出てしまうため気持ちのいいものではありません。

最も遭遇する場面は、mapforなどのループで子コンポーネントを複数呼ぶときでしょう。この時、例えばChildというコンポーネントを呼ぶとき(またはそれをラップする別の要素へ)key属性とユニークな値を付与します。

また、key属性はpropsで子コンポーネントには送れません。そのためkey属性用の変数はkeyでええやろといった気持ちでpropsから受け取ろうとするとバグの原因になります。

また、その気持ちで子コンポーネントでPropsを受け取る時、keyを指定すると受け取る値はundefinedになります。使い方を間違って子で受け取ったkeyの値をkey属性に指定すると怒られます。

正しい例

※以下のコードではkeyに配列の中身の値を設定していますが、重複があったらとかインデックス的な値はよろしくないと言ったベストプラクティス系は無視してください
複数の要素を作るときにkeyを指定する
親コンポーネント

parrent.tsx
import Child from './child'
export const parent = () => {
    const a = [1,2,3,4,5]
    return (<>
        {
            a.map((e: number) => {
                return <Child e={e} key={e} />
            })
        }
        </>)
}
export default parent

子コンポーネント

child.tsx
import React from 'react'
type Props = {
    e:number
}
export const child :React.FC<Props>= ({e}) => {
    return <div>{e}</div>
}
export default child

間違い1

複数呼ばれる子コンポーネント側でkeyを指定する例

Warning: Each child in a list should have a unique "key" prop.

各要素にはユニークなkeyを設定しなさ〜いと言われます。

親コンポーネント

parrent.tsx
import Child from './child'
export const parent = () => {
    const a = [1,2,3,4,5]
    return (<>
        {
            a.map((e: number) => {
-                return <Child e={e} key={e} />
+                return <Child e={e} />
            })
        }
        </>)
}
export default parent

子コンポーネント

child.tsx
import React from 'react'
type Props = {
    e:number
}
export const child :React.FC<Props>= ({e}) => {
-    return <div>{e}</div>
+    return <div key={e}>{e}</div>
}
export default child

間違い2

keyを子要素で受け取って使った

Warning: child: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop.

propskeyを受け取れないのでundefinedですよ。

親コンポーネント

parrent.tsx
import Child from './child'
export const parent = () => {
    const a = [1,2,3,4,5]
    return (<>
        {
            a.map((e: number) => {
                return <Child e={e} key={e}/>
            })
        }
        </>)
}
export default parent

子コンポーネント

child.tsx
import React from 'react'
type Props = {
    e:number,
+    key:number
}
-export const child :React.FC<Props>= ({e}) => {
-    return <div key={e}>{e}</div>
-}
+export const child :React.FC<Props>= ({e,key}) => {
+    return <div key={e}>{e}</div>
+}
export default child

気にしなくても動くことは動くんですけどね。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?