切换数组中对象键值的状态

时间:2018-10-01 19:28:25

标签: reactjs redux react-redux

我需要创建一个化简器,以使用待办事项的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
      };

3 个答案:

答案 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
      };