Обновите отдельное свойство объекта из массива с помощью хука useState () - PullRequest
2 голосов
/ 09 мая 2020

У меня есть массив объектов в хуке состояния todos. И я хочу изменить одно свойство, если оно будет завершено. Кажется, я могу обновить его, но без использования setTodos. Я новичок в React.

  const [todos, setTodos] = useState([]);
  const [input, setInput] = useState("");

  const addTodoHandler = (e) => {
    e.preventDefault();
    if (input.length < 2) return;
    setTodos([...todos, { id: Date.now(), text: input, isComplete: false }]);
    setInput("");
  };

  const removeHandler = (id) => {
    setTodos(todos.filter((todo) => todo.id !== id));
  };

 const completeHandler = (id) => {

    // working without setTodo()
    // errors when added setTodo()
     todos.map((todo) =>
       todo.id === id ? console.log((todo.isComplete = !todo.isComplete)) : ""
     );

  };

      <div className="todolist">
        {todos.map((todo) => (
          <Todo
            key={todo.id}
            id={todo.id}
            text={todo.text}
            removeHandler={removeHandler}
            completeHandler={completeHandler}
            isComplete={todo.isComplete}
          />
        ))}
      </div>

1 Ответ

2 голосов
/ 09 мая 2020

Чтобы исправить это, внутри completeHandler() сначала создайте новый массив, используя метод map(), а внутри map() метод обновите isComplete для текущего todo и просто верните обновленное значение, например:

var updatedTodos = todos.map((todo) => todo.id === id ? {
  ...todo,
  isComplete: !todo.isComplete
} : todo);

Затем внутри setTodos() просто верните этот новый массив updatedTodos, например:

setTodos(updatedTodos);

Вы также можете сделать это в одну строку, например:

setTodos(todos.map((todo) => todo.id === id ? { ...todo, isComplete: !todo.isComplete } : todo));

Но предыдущий код обеспечивает большую читаемость, а также помогает улучшить отладку, если вы хотите проверить каждую переменную построчно.

...