Redux useSelector 未更新,需要刷新

KS *_*eng 0 reactjs redux axios

我面临这个问题。当我有一个 Axios 调用时,它承诺调度一个操作来更新 redux 并执行回调。但是当执行回调时,redux 状态似乎已经过时了。

我在这里有一个用于演示的沙箱代码

如果单击 getNewDate 按钮,控制台将显示 redux 状态的差异。当 redux 导致重新渲染时,状态将是正确的。

如何在回调期间获得正确的 redux 状态?

在此输入图像描述

Zac*_*ber 5

响应将永远是陈旧的,这就是 React hooks 的工作原理。它们在创建时对每个单独渲染中的所有变量应用闭包。如果您绝对需要该值在回调函数(或效果)中不陈旧,请为其设置一个引用。

const { response, getNewDate } = useResponse();
const responseRef = useRef(response);
useLayoutEffect(() => {
    responseRef.current = response;
}, [response]);
const callbackSuccessful = (data: IResponse) => {
    console.log("response is not Stale: " + responseRef.current.newDate);
    console.log("should be: " + data.newDate);
};
Run Code Online (Sandbox Code Playgroud)

设置引用后,您将清楚地看到响应实际上正在更改,并且 responseRef.current 显示与 data.newDate 相同的值。

您必须在这里使用LayoutEffect,因为效果运行的顺序对于回调来说是错误的。由于 useEffect 在组件重新渲染后运行,而 useLayoutEffect 在组件重新渲染时运行。

另一种方式是,您可以看到 useSelector 工作正常并正在更新,并且您的 MyPages.tsx 看到更新是 useEffect 来记录更改(每当更改时)。

useEffect(() => {
  console.log(response.newDate)
}, [response]);
Run Code Online (Sandbox Code Playgroud)

如果你想在回调中访问最新的 redux store 状态而没有任何计时问题,useStore 会很有帮助,而且它根本不会导致重新渲染。

const store = useStore();

const callbackSuccessful = (data: IResponse) => {
    console.log("should be: " + data.newDate);
    console.log("Redux store: " + store.getState().apiResponse.newDate);
};
Run Code Online (Sandbox Code Playgroud)

https://codesandbox.io/s/react-typescript-demo-pek65?file=/src/pages/MyPages.tsx