かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

React TypeScript A props object containing a "key" prop is being spread into JSX

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 に出会う可能性がありそうです

おわり


[参考]