Closed4

Reactでkey propsがundefinedになる

よぺよぺ

現象: key propsがundefinedで子コンポーネントで使えない

mapで複数コンポーネントをレンダリングしようとしたところ、key propsがundefinedになって子コンポーネント側で使用できない。

親コンポーネント側
<Stack direction="row" spacing={2}>
  {kanbanList.map((kanban) => (
    <Kanban
      key={kanban.id}
      name={kanban.name}
      description={kanban.description}
      handleChangeKanban={handleChangeKanban}
      handleDeleteKanban={handleDeleteKanban}
    />
  ))}
</Stack>
子コンポーネント側
type KanbanProps = {
  key: string
  name: string
  description: string
  handleChangeKanban: (
    kanbanId: string,
    kanbanName: string,
    boardId: string
  ) => void
  handleDeleteKanban: (kanbanId: string) => void
}
(中略)
export const Kanban: React.FC<KanbanProps> = (props) => {
  const [taskList, dispatch] = useReducer(
    taskListReducer,
    initialTaskList.filter((task) => task.kanbanId === props.key)
  )
(中略)
  return (
    (中略)
      <CardContent>
        <TaskList
          taskList={taskList}
          changeTaskHandler={handleChangeTask}
          deleteTaskHandler={handleDeleteTask}
        />
      </CardContent>
    (中略)
  )
}

やりたいこと

ReactでTrelloチックなToDoアプリを作成している。
keyの値をfilterメソッドで使ってタスクをフィルタしたい。

よぺよぺ

なるほど。。。
Reactでkey={foo}で渡すのはReactのための仕様であり、子コンポーネント側に渡すには別のpropsで定義する必要があるということか。

https://qiita.com/miyamotokz/items/7386c562593ba4cd0494
https://qiita.com/memomaruRey/items/fb2efa788db2866c2947

公式にも書いてある、、、

https://legacy.reactjs.org/warnings/special-props.html

Most props on a JSX element are passed on to the component, however, there are two special props (ref and key) which are used by React, and are thus not forwarded to the component.

よぺよぺ

修正

親コンポーネント
 <Stack direction="row" spacing={2}>
  {kanbanList.map((kanban) => (
    <Kanban
      key={kanban.id}
+     id={kanban.id}
      name={kanban.name}
      description={kanban.description}
      handleChangeKanban={handleChangeKanban}
      handleDeleteKanban={handleDeleteKanban}
    />
  ))}
 </Stack>
子コンポーネント
type KanbanProps = {
  key: string
+ id: string
  name: string
  description: string
  handleChangeKanban: (
    kanbanId: string,
    kanbanName: string,
    boardId: string
  ) => void
  handleDeleteKanban: (kanbanId: string) => void
}
(中略)
export const Kanban: React.FC<KanbanProps> = (props) => {
  const [taskList, dispatch] = useReducer(
    taskListReducer,
-   initialTaskList.filter((task) => task.kanbanId === props.key)
+   initialTaskList.filter((task) => task.kanbanId === props.id)
  )
(中略)
  return (
    (中略)
      <CardContent>
        <TaskList
          taskList={taskList}
          changeTaskHandler={handleChangeTask}
          deleteTaskHandler={handleDeleteTask}
        />
      </CardContent>
    (中略)
  )
}
このスクラップは2024/03/21にクローズされました