You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何更新多维数组内的复选框状态?

问题原因

  1. Array.forEach() 无返回值,执行后默认返回 undefined,因此你拿到的 updateTodos 必然为undefined
  2. 匹配逻辑错误:你用入参 taskId 和外层todo的 name 字段匹配,而非和tasks数组内对应任务的name匹配,不符合切换单条任务状态的需求
  3. 违反React state不可变更新规则:直接修改原state对象不会触发视图更新,需要生成全新的state副本再调用setTodos赋值

修正后的实现代码

首先注意你的初始种子数据里name: job01缺少字符串引号,需要先修正:

// 修正后的初始种子数据
const datas = [
  {
    id: 10,
    name: "job01", // 补充字符串引号
    tasks: [
      { name: "morning", value: false },
      { name: "afternoon", value: true },
      { name: "sunset", value: false },
      { name: "night", value: true },
    ],
    completed: false
  }
];

切换任务状态的方法修正如下:

const [todos, setTodos] = useState(datas)

const toggleTask = (todoId, taskName) => {
  // 生成新的todos数组,不修改原state
  const updatedTodos = todos.map(todo => {
    // 先匹配到对应外层todo
    if (todo.id === todoId) {
      // 生成新的tasks数组
      const updatedTasks = todo.tasks.map(task => {
        // 匹配到要切换的任务时,返回value取反的新对象,其余原样返回
        if (task.name === taskName) {
          return {...task, value: !task.value}
        }
        return task
      })
      // 返回更新了tasks的新todo对象
      return {...todo, tasks: updatedTasks}
    }
    // 未匹配到的todo原样返回
    return todo
  })
  // 调用setTodos更新state
  setTodos(updatedTodos)
}

调用说明

渲染复选框时,给复选框绑定事件时传入对应外层todo的id和当前任务的name即可:

todos.map(todo => (
  <div key={todo.id}>
    <h3>{todo.name}</h3>
    {todo.tasks.map(task => (
      <label key={task.name}>
        <input 
          type="checkbox" 
          checked={task.value} 
          onChange={() => toggleTask(todo.id, task.name)} 
        />
        {task.name}
      </label>
    ))}
  </div>
))

内容的提问来源于stack exchange,提问作者Rioko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:15:04