Javascript 为什么我的设置状态只更新一次? const[invalidateCacheKey,setInvalidateCacheKey]=useState(0); const onchange=()=>{ 设置invalidateCacheKey(invalidateCacheKey+1); 突变(); }; const selectOrder=()=>{ 派遣( showmodel(‘拍摄、操作、查看’{ modalType:“操作视图”, modalProps:{ 内容:, }, }) ); };
我有一个功能组件,我正在使用useState更新invalidateCacheKey计数器的状态 然后我有一个显示模式的分派方法(react-redux),我将回调(onChangeAssignee)传递给模式 问题在于:当启动回调时,onChangeAssignee方法内的状态(invalidateCacheKey)没有改变(在onChangeAssignee方法内运行回调日志记录状态前后为0),而在功能组件内(记录useState声明后的状态)状态(invalidateCacheKey)回调前为0,回调后为1 我认为问题在于分派方法,它“存储”我的状态,而不更新它Javascript 为什么我的设置状态只更新一次? const[invalidateCacheKey,setInvalidateCacheKey]=useState(0); const onchange=()=>{ 设置invalidateCacheKey(invalidateCacheKey+1); 突变(); }; const selectOrder=()=>{ 派遣( showmodel(‘拍摄、操作、查看’{ modalType:“操作视图”, modalProps:{ 内容:, }, }) ); };,javascript,reactjs,redux,Javascript,Reactjs,Redux,我有一个功能组件,我正在使用useState更新invalidateCacheKey计数器的状态 然后我有一个显示模式的分派方法(react-redux),我将回调(onChangeAssignee)传递给模式 问题在于:当启动回调时,onChangeAssignee方法内的状态(invalidateCacheKey)没有改变(在onChangeAssignee方法内运行回调日志记录状态前后为0),而在功能组件内(记录useState声明后的状态)状态(invalidateCacheKey)回调
如何解决这个问题?Ciao,不幸的是react中的钩子是异步的,因此如果您尝试编写以下内容:
const [invalidateCacheKey, setInvalidateCacheKey] = useState(0);
const onChangeAssignee = () => {
setInvalidateCacheKey(invalidateCacheKey + 1);
mutate();
};
const selectOrder = () => {
dispatch(
showModal('SHOOTING_OPERATIONAL_VIEW', {
modalType: 'OPERATIONAL_VIEW',
modalProps: {
content: <ShootingActionsView updateOrders={mutate} onChangeAssignee={onChangeAssignee} />,
},
})
);
};
useEffect(() => { // this will be triggered every time invalidateCacheKey changes
console.log(invalidateCacheKey) // this shows the la st value of invalidateCacheKey
}, [invalidateCacheKey])
您将记录一个旧值invalidateCacheKey
,因为setInvalidateCacheKey
是异步的。要在react钩子中获得更新值,可以使用useffect
hook-like:
const onChangeAssignee = () => {
setInvalidateCacheKey(invalidateCacheKey + 1);
console.log(invalidateCacheKey)
...
};
const onChangeAssignee = () => {
setInvalidateCacheKey(invalidateCacheKey + 1);
dostuff(invalidateCacheKey) // dostuff takes an old value of invalidateCacheKey so it doesn't work
};
作为替代方案,您可以使用库。使用此库,您可以编写如下内容:
const [invalidateCacheKey, setInvalidateCacheKey] = useState(0);
const onChangeAssignee = () => {
setInvalidateCacheKey(invalidateCacheKey + 1);
mutate();
};
const selectOrder = () => {
dispatch(
showModal('SHOOTING_OPERATIONAL_VIEW', {
modalType: 'OPERATIONAL_VIEW',
modalProps: {
content: <ShootingActionsView updateOrders={mutate} onChangeAssignee={onChangeAssignee} />,
},
})
);
};
useEffect(() => { // this will be triggered every time invalidateCacheKey changes
console.log(invalidateCacheKey) // this shows the la st value of invalidateCacheKey
}, [invalidateCacheKey])
注意:react钩子中始终不鼓励设置状态读取状态本身。我建议你这样做:
import useStateWithCallback from 'use-state-with-callback';
...
const [invalidateCacheKey, setInvalidateCacheKey] = useStateWithCallback(0, invalidateCacheKey => {
console.log(invalidateCacheKey) // here you have the last value of invalidateCacheKey
});
或
编辑
现在,假设您需要在onChangeAssignee
函数中使用invalidateCacheKey
。假设您编写了如下代码:
const onChangeAssignee = () => {
let appo = invalidateCacheKey;
setInvalidateCacheKey(appo + 1);
...
};
您可以通过将dostuff
移动到useffect
hook-like中来解决此问题:
const onChangeAssignee = () => {
setInvalidateCacheKey(invalidateCacheKey + 1);
console.log(invalidateCacheKey)
...
};
const onChangeAssignee = () => {
setInvalidateCacheKey(invalidateCacheKey + 1);
dostuff(invalidateCacheKey) // dostuff takes an old value of invalidateCacheKey so it doesn't work
};
再见,只要写几行代码就可以了。请:)你能在问题中粘贴你的代码吗?请,有图像让我们很难在我们这边尝试,也请看这个帮助页面@GiovanniEsposito对不起,现在是clear@jonatjano你说得对,现在检查一下:我在这件事上帮不了你,我从来没有用过react/redux,但至少现在你的问题没有那么令人沮丧了汉克斯·乔瓦尼!我知道什么是useEffect,以及如何使用他的依赖项数组,但我不明白:我需要将useEffect放在哪里,它如何帮助我?Ciao,我的答案只是要指出,您在这里写的是“当回调被触发时,OnChangeAssignment方法内的状态(invalidateCacheKey)不会改变。”(在onChangeAssignee方法中运行回调日志状态之后和之前为0),”是不正确的,因为在
onChangeAssignee
上的状态实际上发生了更改,但您无法记录它,因为setInvalidateCacheKey
是异步的。在代码示例中显示的组件中放入useEffect
只允许您检查invalidateCacheKey
是否由setInvalidateCacheKey
设置。好的,但是无法解决我的问题,我可以在状态更改时使用useEffect进行检查,但我不能在onChangeAssignee中使用我状态的新值是的,您不能直接使用invalidateCacheKey
,但在`onChangeAssignee`中,您拥有所需的所有数据。因为您知道在onChangeAssignee
函数中,`invalidateCacheKey`将递增1,这样实际上您就知道invalidateCacheKey
的下一个值是什么。因此,一个可能的解决方案是将invalidateCacheKey
复制到一个变量中,递增1这个变量并将其用于您的范围。类似于让appo=invalidateCacheKey;appo=appo+1;
这样您就可以使用appo li了ke它是invalidateCacheKey
。再见,Giovanni。非常感谢您的支持。我整天都在解决这个问题,我知道问题是关于react redux的:当我将onChangeAssignee方法作为prop传递给ShootingActionsView组件时,该方法是“存储”的而且,如果另一个组件更改了状态,onChangeAssignee将重新呈现,但新的onChangeAssignee方法不会传递给ShootingActionsView组件,因此仅在父组件中重新呈现,而不是在ShootingActionsView组件中重新呈现,该组件“存储”旧状态,从而设置错误的状态