为什么我的setState仅更新一次状态?

时间:2020-08-10 08:41:51

标签: javascript reactjs redux

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} />,
      },
    })
  );
};

我有一个功能组件,我正在使用useState更新我的invalidateCacheKey计数器的状态。

然后,我有一个显示模式的调度方法(react-redux),然后将回调(onChangeAssignee)传递给模式。

问题是:触发回调后,状态(invalidateCacheKey)在onChangeAssignee方法内部(在onChangeAssignee方法内部运行回调日志记录状态之后和之前为0)在功能组件内部(在useState声明之后记录状态)。状态(invalidateCacheKey)在回调之前为0,在回调之后为1。

我认为问题是调度方法,它“存储”我的状态,并且不会更新它。

该如何解决?

1 个答案:

答案 0 :(得分:1)

Ciao,不幸的是,react中的钩子是异步的,因此,如果您尝试编写如下内容:

std::begin

您将记录旧值const onChangeAssignee = () => { setInvalidateCacheKey(invalidateCacheKey + 1); console.log(invalidateCacheKey) ... }; ,因为正如我告诉您的那样,invalidateCacheKey是异步的。要获得react挂钩中的更新值,您可以使用setInvalidateCacheKey挂钩,例如:

useEffect

或者,您可以使用use-state-with-callback库。使用该库,您可以编写如下内容:

useEffect(() => { // this will be triggered every time invalidateCacheKey changes
   console.log(invalidateCacheKey) // this shows the la st value of invalidateCacheKey
}, [invalidateCacheKey])

注意:在反应钩子中始终不鼓励设置状态读取状态本身。我建议您使用这种方式:

import useStateWithCallback from 'use-state-with-callback';
...

const [invalidateCacheKey, setInvalidateCacheKey] = useStateWithCallback(0, invalidateCacheKey => {
    console.log(invalidateCacheKey)  // here you have the last value of invalidateCacheKey
});

const onChangeAssignee = () => {
  setInvalidateCacheKey(invalidateCacheKey => invalidateCacheKey + 1);
  ...
};

编辑

现在可以说您需要在const onChangeAssignee = () => { let appo = invalidateCacheKey; setInvalidateCacheKey(appo + 1); ... }; 函数中使用invalidateCacheKey。假设您这样编写代码:

onChangeAssignee

您可以通过将const onChangeAssignee = () => { setInvalidateCacheKey(invalidateCacheKey + 1); dostuff(invalidateCacheKey) // dostuff takes an old value of invalidateCacheKey so it doesn't work }; 移到dostuff钩子中来解决此问题,例如:

useEffect