简体   繁体   English

为什么我的 setState 只更新 state 一次?

[英]Why is my setState updating state only once?

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

I have a functional component, I'm using useState to update the state of my invalidateCacheKey counter.我有一个功能组件,我正在使用 useState 来更新我的 invalidateCacheKey 计数器的 state。

Then I have a dispatch method (react-redux) that displays a modal, I pass to the modal the callback (onChangeAssignee).然后我有一个显示模式的调度方法(react-redux),我将回调(onChangeAssignee)传递给模式。

The problem is that: when the callback is fired the state (invalidateCacheKey) doesn't change inside the onChangeAssignee method (it is 0 after and before run the callback logging state inside the onChangeAssignee method), while inside the functional component (logging the state after useState declaration) the state (invalidateCacheKey) is 0 before the callback and is 1 after the callback. The problem is that: when the callback is fired the state (invalidateCacheKey) doesn't change inside the onChangeAssignee method (it is 0 after and before run the callback logging state inside the onChangeAssignee method), while inside the functional component (logging the state useState 声明后)state(invalidateCacheKey)在回调之前为 0,在回调之后为 1。

I think that problem is dispatch method, it "stores" my state and it doesn't update it.我认为问题在于调度方法,它“存储”了我的 state 并且没有更新它。

How to fix that?如何解决?

Ciao, unfortunately hooks in react are async so if you try to write something like: Ciao,不幸的是,react 中的钩子是异步的,所以如果你尝试编写如下内容:

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

you will log an old value of invalidateCacheKey , because setInvalidateCacheKey is async as I told you.您将记录invalidateCacheKey的旧值,因为setInvalidateCacheKey正如我告诉您的那样是异步的。 To get updated value in react hooks you could use useEffect hook like:要在反应钩子中获得更新的值,您可以使用useEffect钩子,例如:

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

As an alternative, you could use a use-state-with-callback library.作为替代方案,您可以使用use-state-with-callback库。 With this library you could write something like:使用这个库,您可以编写如下内容:

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

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

Note: set state reading state itself is always discouraged in react hooks.注意:在反应钩子中总是不鼓励将 state 设置为 state 本身。 I suggest you to use this way:我建议你使用这种方式:

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

or或者

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

EDIT编辑

Now lets say you need to use invalidateCacheKey in onChangeAssignee function.现在假设您需要在onChangeAssignee function 中使用invalidateCacheKey Lets suppose you worte code like this:让我们假设您编写这样的代码:

const onChangeAssignee = () => {
  setInvalidateCacheKey(invalidateCacheKey + 1);
  dostuff(invalidateCacheKey) // dostuff takes an old value of invalidateCacheKey so it doesn't work
};

You can solve this by moving dostuff into useEffect hook like:您可以通过将dostuff移动到useEffect挂钩来解决此问题,例如:

useEffect(() => {
   dostuff(invalidateCacheKey) // here dostuff works because it takes last value of invalidateCacheKey
}, [invalidateCacheKey])

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM