【问题标题】:React useState hook isn't updating the stateReact useState 钩子没有更新状态
【发布时间】:2019-02-20 14:56:38
【问题描述】:

我遇到了 useState 问题。下面是codesandbox中运行的代码

https://codesandbox.io/s/kmznl0345r

这是代码本身;

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);

单击完成按钮时,它只运行一次completeTodo 函数,即使运行 setTodos 函数并且更新了 todos,它也不会再次运行。

这曾经在react 16.7.0-alpha-2 中工作,但现在使用版本16.8.1 似乎没有更新。

如果您有任何建议,请告诉我,这里再次是在代码沙箱中运行的代码;

https://codesandbox.io/s/kmznl0345r

【问题讨论】:

  • 我相信这在 16.8 中由于这个变化而中断了:github.com/facebook/react/pull/14569。在 completeTodo 中,newTodos === todos 即使在更改之后也是 true,因为您正在对同一个数组进行变异。

标签: javascript reactjs react-hooks


【解决方案1】:

您当前正在修改您的 completeTodo 函数中的 todo 对象。如果您改为使用 todos 中的所有元素创建一个新数组,并创建一个切换 complete 的新对象,它将按预期工作。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    • 2020-04-29
    • 2021-04-17
    • 2020-11-29
    相关资源
    最近更新 更多