【发布时间】:2021-01-04 17:51:34
【问题描述】:
我找到了很多这方面的例子,但没有一个使用 Redux 和useDispatch,所以情况是这样的......
我有一个带有像这样的异步操作的操作文件...
//postsActions.tsx
export const asyncGetPostById = (postId: string) => {
return async (dispatch: any, getState: () => AppState) => {
try {
dispatch(startLoader());
const { data } = await axios.get(`api/posts/${postId}`);
dispatch(setPostDataInReducer(data));
} catch (error) {
console.log(error)
}
};
};
我在 Post.tsx 组件中调用这个动作,就像这样......
const dispatch = useDispatch();
useEffect(() => {
dispatch(asyncGetPostById(postId));
}, []);
这当然是一个简化的版本,但它的想法是一样的。现在我怎样才能清理像useEffect 这样的调度以避免这个错误......
警告:无法对未安装的组件执行 React 状态更新。 这是一个空操作,但它表明您的应用程序中存在内存泄漏。 要修复,请取消 useEffect 中的所有订阅和异步任务 清理功能。
编辑
这个想法是如何取消 ComponentWillUnmount 上的请求(或者在我的情况下是 useEffect 中的清理功能),如果它还没有完成,这样你就不会在后台有过时或未解决的请求,这将使你的应用程序慢。
这是一个非常常见的问题,很多人都成为受害者,并且有很多解决方案,但不适用于这种特殊情况(使用 dispatch 和 redux)。
有些使用AbortController(),有些使用axios.CancelToken,但我不知道在我的情况下如何使用它们。
【问题讨论】:
-
axios.get解决时组件可能已卸载的问题?我能想到一个丑陋的解决方案(传入一个在卸载时发生突变的对象),希望有更好的解决方案 -
是的,这就是问题所在,有些使用
axios.CancelToken,有些使用AbortController,但我不知道在这种情况下如何在dispatch和redux中使用这些。 -
这个想法是如何取消 ComponentWillUnmount 上的请求,如果它还没有完成,这样您就不会在后台有陈旧或未解决的请求,这会使您的应用程序变慢。
-
这不应该引发错误,除非您在请求完成后设置要声明的内容。但是,如果您想取消请求,那么您将使用您提到的选项之一(尽管AbortController 在某些浏览器中不起作用)。另一种方法是使用 redux sagas 而不是 thunk,它允许您手动取消任务。也就是说,如果没有 repo 或工作演示,就很难推荐最佳方法。
-
@MattCarlotta 我确实在请求之后更改了状态,或者更确切地说是减速器,在某些情况下,我调度了另一个异步操作,它也更新了减速器。我只需要知道如何取消上述示例中的请求即可。
标签: reactjs redux react-hooks next.js use-effect