React useState 钩子不更新状态
React useState hook isn't updating the state
我遇到了 useState 问题。下面是codesandbox
中的代码运行ning
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 函数是 运行并且待办事项已更新。
这曾经在 react 16.7.0-alpha-2
中有效,但现在版本 16.8.1
似乎无法更新。
如果您有任何建议,请告诉我,这里再次显示代码 运行ning in codesandbox;
您目前正在改变 completeTodo
函数中的 todo
对象。如果您改为使用 todos
中的所有元素创建一个新数组,并在 complete
切换的位置创建一个新对象,它将按预期工作。
const completeTodo = (index: number): void => {
const newTodos: ITodo[] = [...todos];
newTodos[index] = {
...newTodos[index],
complete: !newTodos[index].complete
};
setTodos(newTodos);
};
我遇到了 useState 问题。下面是codesandbox
中的代码运行ninghttps://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 函数是 运行并且待办事项已更新。
这曾经在 react 16.7.0-alpha-2
中有效,但现在版本 16.8.1
似乎无法更新。
如果您有任何建议,请告诉我,这里再次显示代码 运行ning in codesandbox;
您目前正在改变 completeTodo
函数中的 todo
对象。如果您改为使用 todos
中的所有元素创建一个新数组,并在 complete
切换的位置创建一个新对象,它将按预期工作。
const completeTodo = (index: number): void => {
const newTodos: ITodo[] = [...todos];
newTodos[index] = {
...newTodos[index],
complete: !newTodos[index].complete
};
setTodos(newTodos);
};