はじめに
みんな嫌いな↓のエラー。
Each child in a list should have a unique "key" prop.
「はいはいkey指定すれば良いんでしょ」と思ったのに、エラーが消えない❗
エラーが出るコードは↓。
{arrays.map((element) => (
<>
<div key={`${element}1`}>ほげ</div>
<div key={`${element}2`}>ふが</div>
</>
))}
結論
↓のようにすればよい。あ、 Fragment
はちゃんと import
してね。
{arrays.map((element) => (
<Fragment key={element}>
<div>ほげ</div>
<div>ふが</div>
</Fragment>
))}
keyはループする要素の最上位の要素に指定しないと意味がない
React公式docの↓の記述が該当するかな。
Keys used within arrays should be unique among their siblings.
で、ここで疑問なのが最上位の要素...っぽい <>
ってそもそもなんなの❓ってこと。
<>
ってなんぞや❓
これはShort Syntaxで、正式には Fragments
というらしい。
公式docはこちら。
A common pattern in React is for a component to return multiple elements.
CSS gridを使ってるときなど、複数の要素を div
で囲まずにダラーっと並べたいときによく使う。
混乱しやすいのは、reactのツリー構造とreactが吐くHTMLのツリー構造が違うこと。
Reactでは
- Fragment1
- div:ほげ
- div:ふが
- Fragment2
- div:ほげ
- div:ふが
のようになっているが、HTMLは
- div:ほげ
- div:ふが
- div:ほげ
- div:ふが
のようになっている。
ここで、keyを指定すべき最上位要素とはreactのツリー構造で考えなくてはならない。
よって、 div
要素じゃなく Fragment
要素に key
を指定する必要があるってわけ。
なお、 <>
記法のときは key
が指定できないとのこと。なぜ😭
You can use
<>
</>
the same way you’d use any other element except that it doesn’t support keys or attributes.