React Redux-在调度问题之前快速刷新以前的状态



我正在构建一个带有Node.js后端的React+Redux应用程序,其中一个功能是用户可以查看其他用户的配置文件。为此,我在Redux state中有一个名为users的部分,看起来像:

{
...,
users: {
user: {},
isLoading: true
}
}

每次呈现/users/:id路由时,都会调度一个getUser(id)动作,并用接收到的信息填充状态。

主要问题是,当用户查看user1的配置文件页面(因此redux状态现在用user1的概要文件填充(,然后查看user2的配置文件页时,会在页面呈现后立即调用dispatchgetUser(2)操作。由于user1的信息仍处于状态,它会在很短的时间内闪烁他们的信息,然后显示加载微调器,直到加载新用户。

我读过关于在每次卸载页面时调度resetUser(id)操作的文章,但我不确定这是否是正确的做法。此外,其中一个功能是,如果用户正在查看自己的页面,他们会有一个编辑按钮,将其重定向到/edit-profile。如果我在每次卸载时重置状态,我将不得不再次获取他们的配置文件(在编辑页面中(,尽管我只是在他们查看页面时这样做的。。这似乎没有道理。

有什么办法解决这个问题吗?谢谢

render阶段在mounting之后运行。您指出,以前的数据显示在新数据之前。看来你有异步挂载:

async componentDidMount() {}

即使在安装阶段完成之前,它也将继续渲染。为了避免问题,您可以使用同步性质的挂载:

componentDidMount(){}

您将在哪里调用api数据。

现在,当您进入渲染阶段时,它将在渲染之前有新的数据可用,并且不会闪烁旧数据。


您现在可能想知道如何异步调用api。您可以创建一个异步函数,并在同步组件DidMount中调用该函数。

componentDidMount() {
yourAsyncFunc()
}
async yourAsyncFunc() {} // api call

如何使用React钩子实现这一点?

使用useEffect时,不要实现异步:

useEffect(async () => 

简单实现:

useEffect(() => {
// you can still use asynchronous function here
async function callApi() {}
callApi()
}, []) // [] to run in similar to componentDidMount

如果您错过了useEffect的第二个参数,那么您就不能确保它在安装阶段运行。它将根据具体情况在渲染之前、之后和渲染阶段运行。

实现类似resetUser(id)的东西似乎是正确的方法。我在当前的项目中使用了这种方法,这确实解决了问题。另一个答案中提到的从useEffect回调中删除async关键字的另一种方法对我不起作用(我使用hook、redux toolkit、Typescript(。

调度此操作后,您的状态应该类似

{
...,
users: {
user: null,
isLoading: false,
}
}

如果你正在使用钩子,你可以这样调度动作:

useEffect(() => {
const ac = new AbortController();
...
return () => {
dispatch(resetUser(null));
ac.abort();
};
}, []);

行动可能看起来像这样:

resetListingDetails(state, action) {
// Immer-like mutable update
state.users = {
...state.users,
user: null,
};
}

最新更新