问题是:我试图通过单击按钮调用两个函数。这两个函数都会更新状态(我正在使用useState钩子)。第一个函数将value1正确更新为“new 1”,但在1s(setTimeout)后,第二个函数启动,它将值2更改为“new 2”,但是!它将值1设置回“1”。为什么会这样?提前谢谢!
import React, { useState } from "react";
const Test = () => {
const [state, setState] = useState({
value1: "1",
value2: "2"
});
const changeValue1 = () => {
setState({ ...state, value1: "new 1" });
};
const changeValue2 = () => {
setState({ ...state, value2: "new 2" });
};
return (
<>
<button
onClick={() => {
changeValue1();
setTimeout(changeValue2, 1000);
}}
>
CHANGE BOTH
</button>
<h1>{state.value1}</h1>
<h1>{state.value2}</h1>
</>
);
};
export default Test;
当调用ChangeValue2
时,初始状态保持不变,因此状态会返回初始状态,然后写入value e2
属性。
之后下次调用changeValue2
时,它将保持状态{value1:“1”,value2:“new 2”}
,因此将覆盖value1
属性。
setState
参数需要一个箭头函数。
const Test = () => {
const [state, setState] = React.useState({
value1: "1",
value2: "2"
});
const changeValue1 = () => {
setState(prev => ({ ...prev, value1: "new 1" }));
};
const changeValue2 = () => {
setState(prev => ({ ...prev, value2: "new 2" }));
};
return (
<React.Fragment>
<button
onClick={() => {
changeValue1();
setTimeout(changeValue2, 1000);
}}
>
CHANGE BOTH
</button>
<h1>{state.value1}</h1>
<h1>{state.value2}</h1>
</React.Fragment>
);
};
ReactDOM.render(<Test />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
你的功能应该是这样的:
const changeValue1 = () => {
setState((prevState) => ({ ...prevState, value1: "new 1" }));
};
const changeValue2 = () => {
setState((prevState) => ({ ...prevState, value2: "new 2" }));
};
因此,通过在触发操作时使用前一个状态,可以确保当前状态中没有丢失任何现有属性。因此,您还可以避免管理闭包。
欢迎来到关闭地狱。发生此问题是因为每当调用setState
时,state
都会获得一个新的内存引用,但是由于闭包,函数Change eValue1
和Change eValue2
会保留旧的初始state
引用。
确保setState
fromChangeValue1
和ChangeValue2
获得最新状态的解决方案是通过使用回调(将前一个状态作为参数):
import React, { useState } from "react";
const Test = () => {
const [state, setState] = useState({
value1: "1",
value2: "2"
});
const changeValue1 = () => {
setState((prevState) => ({ ...prevState, value1: "new 1" }));
};
const changeValue2 = () => {
setState((prevState) => ({ ...prevState, value2: "new 2" }));
};
// ...
};
你可以在这里和这里找到关于这个关闭问题的更广泛的讨论。
我想用React useState钩子设置多个状态值,这样我就可以用useEffect钩子分别更新它们。我有以下代码: 但是当我用React DevTools检查应用程序时,我会看到钩子的多个“状态”值,而不是“订单”、“支付”、“提交”等。
我有一个对象的状态数组: 我有一个添加按钮,用于将对象添加到数组中,这是onclick事件的主体:
我正在迁移React with TypeScript项目以使用钩子特性(React v16.7.0-alpha),但我不知道如何设置分解结构元素的类型。 以下是一个例子: 我想强制变量类型为。我唯一成功的试验是分两个阶段进行:打字,然后初始化: 但我相信有更好的办法。另外,应该初始化为一个函数,该函数将作为输入,并且不返回任何内容。 另外,值得注意的是,使用
我有一个React函数组件,沿着遗留的JQuery应用程序运行。在JQuery元素上调用事件处理程序时,传递当前React状态默认值为初始状态值,而不是更新后的状态值。 已验证的x状态正在通过useEffect钩子更改,但在调用事件侦听器时,x设置为初始状态值,而不是更新后的状态值。 不会显示任何错误消息。在本文的上述代码中,我希望onXSave方法调用中的x状态为true,但它一直显示为fals
问题内容: 当我用酶测试类组件时,我可以设置状态。当我用钩子测试功能组件时,现在该怎么做? 例如,在我的组件中,我有: 我想在测试中进行更改 问题答案: 使用挂钩状态时,您的测试必须忽略诸如状态之类的实现细节,以便对其进行正确测试。您仍然可以确保组件将正确的状态传递到其子级。 您可以在Kent C. Dodds撰写的这篇博客文章中找到一个很好的例子。 这是摘录的代码示例。 依赖状态执行细节的测试-
我正在React中使用useState钩子,状态将不会在