我的反应组件中有一个简单的 material-ui 切换。我想用它来切换状态(假/真)。如果我第一次单击切换开关时以 useState(false) 开头,它说的是假而不是真。
我想知道另一个反应钩子是否会解决这个问题。 useEffect, useCallback...
const Component = () => {
const [toggleValue, setToggleValue] = useState(false);
const handleToggleChange = () => {
setToggleValue(!toggleValue);
console.log("toggle value in handle: " + toggleValue);
};
return(
<FormControlLabel
control={
<Switch
checked={toggleValue}
onChange={handleToggleChange}
value="my toggle"
/>
}
/>
);
};
我希望setPreseason(!preseason);
将状态设置为与当前状态相反的状态。真对假,假对真。
可能是,但是当我在下一行记录状态时,它会记录初始状态,并且始终记录与切换
相反的状态。useState
返回的state updater function
是异步
的如果您需要对state
变化做出反应useEffect
就是您的最佳选择
const Component = () => {
const [toggleValue, setToggleValue] = useState(false);
const handleToggleValue = () => {
setToggleValue(!toggleValue);
};
useEffect(() => {
console.log("toggleValue: " + toggleValue);
// second argument to useEffect is an array of dependencies
// this function is going to run every time one of the dependencies
// changes
}, [toggleValue])
return (
<FormControlLabel
control={
<Switch
checked={toggleValue}
onChange={handleToggleValue}
value="my toggle"
/>
}
/>
);
}
问题是关于闭包内部toggleValue
哪个值。不是你所期望的。而是将回调传递给setToggleValue
。您将恢复当前状态,然后可以更改。
const handleToggleValue = () => {
setToggleValue((toggleValue) => !toggleValue);
}
你做对了,只是toggleValue
只是一个局部变量,不能仅仅通过调用setToggleValue
来改变(状态将被改变,但这是异步发生的)。
你可以做这样的事情:
const handleToggleValue = () => {
const newToggleValue = !toggleValue;
setToggleValue(newToggleValue);
console.log('toggleValue: ' + newToggleValue);
}
这取决于您对新切换值的意图。这只是修复了您使用控制台.log调用所执行的操作。但是,鉴于您在更新状态之前使用的是新的切换值,因此在此之后您可能会遇到进一步的麻烦。但这是另一个SO问题...