简体   繁体   English

反应useState钩子不更新状态

[英]React useState hook isn't updating the state

I am experiencing an issue with useState. 我遇到了useState问题。 Below is the code running in codesandbox 下面是在codesandbox中运行的代码

https://codesandbox.io/s/kmznl0345r https://codesandbox.io/s/kmznl0345r

Here is the code itself; 这是代码本身;

import React, { Fragment, useState } from "react";
import ReactDOM from "react-dom";

type FormElem = React.FormEvent<HTMLFormElement>;

interface ITodo {
  text: string;
  complete: boolean;
}

export default function App(): JSX.Element {
  const [value, setValue] = useState<string>("");
  const [todos, setTodos] = useState<ITodo[]>([]);

  const handleSubmit = (e: FormElem): void => {
    e.preventDefault();
    addTodo(value);
    setValue("");
  };

  const addTodo = (text: string): void => {
    const newTodos: ITodo[] = [...todos, { text, complete: false }];
    setTodos(newTodos);
  };

  const completeTodo = (index: number): void => {
    const newTodos: ITodo[] = todos;
    newTodos[index].complete = !newTodos[index].complete;
    setTodos(newTodos);
  };

  return (
    <Fragment>
      <h1>Todo List</h1>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={value}
          onChange={e => setValue(e.target.value)}
          required
        />
        <button type="submit">Add Todo</button>
      </form>
      <section>
        {todos.map((todo: ITodo, index: number) => (
          <Fragment key={index}>
            <div>{todo.text}</div>
            <button type="button" onClick={() => completeTodo(index)}>
              {" "}
              {todo.complete ? "Incomplete" : "Complete"}{" "}
            </button>
          </Fragment>
        ))}
      </section>
    </Fragment>
  );
}

const root = document.getElementById("root");

ReactDOM.render(<App />, root);

When the complete button is clicked it only runs the completeTodo function once, and it doesn't run again even though the setTodos function is run and the todos are updated. 单击完成按钮时,它仅运行一次completeTodo函数,即使setTodos函数已运行并且待办事项已更新,它也不会再次运行。

This used to work in react 16.7.0-alpha-2 but now with version 16.8.1 it seems not to update. 这曾经在react 16.7.0-alpha-2起作用,但现在在16.8.1版本中似乎没有更新。

Let me know any suggestions you have, and once again here is the code running in codesandbox; 让我知道您有任何建议,这里再次是在codeandbox中运行的代码;

https://codesandbox.io/s/kmznl0345r https://codesandbox.io/s/kmznl0345r

You are currently mutating the todo object in your completeTodo function. 您当前正在您的completeTodo函数中todo对象。 If you instead create a new array with all the elements in todos and create a new object where complete is toggled it will work as expected. 如果改为使用todos所有元素创建一个新数组,并在切换complete位置创建一个新对象,则它将按预期工作。

const completeTodo = (index: number): void => {
  const newTodos: ITodo[] = [...todos];
  newTodos[index] = {
    ...newTodos[index],
    complete: !newTodos[index].complete
  };
  setTodos(newTodos);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM