我需要创建一个化简器,以使用待办事项的ID或索引切换完成状态
state = {
todos: [
{
title: "eat rice",
done: false,
id: 1
},
{
title: "go fishing",
done: true,
id: 2
},
{
title: "drink coffee",
done: false,
id: 3
}
]
}
我尝试了这个,但是它改变了状态,有效载荷是对象在数组中的索引。
case "DONE":
const todos = [...state.todos];
todos[action.payload].done = !todos[action.payload].done;
return {
...state,
todos: todos
};
答案 0 :(得分:1)
您可以改用map
函数。该函数将生成一个新数组,可用于将todos
替换为。
case "DONE":
const newTodos = state.todos.map((todo, index) => {
// Based on your code, I assume action.payload is the index of the todo in the array of todos
if (index === action.payload) {
const newTodo = {...todo};
todo.done = !todo.done;
return todo;
}
return todo;
});
return {
...state,
todos: newTodos,
};
如果您不想遍历每个todo
,则可以执行其他操作,例如使用slice
创建数组的副本,然后更改一个值:
case "DONE":
const newTodos = todos.slice();
const updatedTodo = {...newTodos[action.payload]};
updatedTodo.done = !updatedTodo.done;
newTodos[action.payload] = updatedTodo;
return {
...state,
todos: newTodos,
};
答案 1 :(得分:0)
使用散布运算符或映射将创建一个新数组,但不会自动克隆所包含的对象,因为JavaScript遵循“按引用传递”。您还必须克隆对象。所以也许像
case "DONE":
const todos = state.todos.map((todo, index) => {
const newTodo = {...todo};
if (action.payload === index) {
newTodo.done = !todo.done;
}
return newTodo;
});
return {
...state,
todos,
};
当然,您也可以使用克隆工具或类似Immutable.js的东西。
答案 2 :(得分:0)
找到了答案。感谢您的贡献。
case "DONE":
const newTodos = state.todos.map((todo, index) => {
if (index === action.payload) {
const newTodo = { ...todo };
newTodo.done = !newTodo.done;
return newTodo;
}
return todo;
});
return {
...state,
todos: newTodos
};