React中如何更新多维数组内的复选框状态?
问题原因
Array.forEach()无返回值,执行后默认返回undefined,因此你拿到的updateTodos必然为undefined- 匹配逻辑错误:你用入参
taskId和外层todo的name字段匹配,而非和tasks数组内对应任务的name匹配,不符合切换单条任务状态的需求 - 违反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
相关产品推荐
相关产品推荐

