React v.18 で作成したアプリで A props object containing a "key" prop is being spread into JSX
という Warning が発生した
Warning: props object containing a "key" prop is being spread into JSX: let props = {key: someKey, label: ..., size: ..., className: ..., disabled: ..., data-tag-index: ..., tabIndex: ..., onDelete: ...}; <Component {...props} /> React keys must be passed directly to JSX without using spread: let props = {label: ..., size: ..., className: ..., disabled: ..., data-tag-index: ..., tabIndex: ..., onDelete: ...}; <Component key={someKey} {...props} />
key
というプロパティは特別なのでスプレッド構文で渡さないように。ということらしい
key
というプロパティが含まれる props は key
だけは別途抜き出す必要がある
今回 Warning が発生したコンポーネントはループで呼び出しているわけではなく、 Database から取ってきたデータに key
というプロパティが存在したのでこの警告が発生していた。
Warning が発生していたコンポーネントの呼び出し
type ComponentDataType = { id: string; key: string; ... }; const App: FC = () => { const data: ComponentDataType[] = getComponentData(); return ( <ul> {data.map((item) => ( <li key={item.id}> <MyComponent {...item} /> </li> )} </ul> ); };
item
に key
という名前のプロパティが存在するので、<MyComponent {...item} />
で A props object containing a "key" prop is being spread into JSX
の警告が発生する
別途 key
を切り出して渡せば OK
type ComponentDataType = { id: string; key: string; ... }; const App: FC = () => { const data: ComponentDataType[] = getComponentData(); return ( <ul> {data.map(({key, ...item}) => ( <li key={item.id}> <MyComponent {...item} /> </li> )} </ul> ); };
ループで作られる子に設定する key
でなくても、 key
という名前の props は切り出して渡す必要がある
コンポーネントで key
が不要なら {key: _key, ...item}
とすれば OK
コンポーネントの props として key
という名前のプロパティを使ったり、外から取得するデータに key
というプロパティがあるとこの warning に出会う可能性がありそうです
おわり
[参考]