[英]How to clean up a Redux "useDispatch" action inside useEffect?
I found a lot of examples for this, but none uses Redux and useDispatch
, so here's the situation ...我为此找到了很多示例,但没有一个使用 Redux 和
useDispatch
,所以情况如下......
I have an action file with an async action like this ...我有一个像这样的异步动作的动作文件......
//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)
}
};
};
And I'm calling this action inside the Post.tsx
component like this ...我像这样在
Post.tsx
组件中调用这个动作......
const dispatch = useDispatch();
useEffect(() => {
dispatch(asyncGetPostById(postId));
}, []);
This is of course a simplified version, but it's the same idea.这当然是一个简化版本,但它的想法是一样的。 Now how can I clean up a dispatch like that in
useEffect
to avoid this error ...现在我如何清理
useEffect
中这样的调度以避免这个错误......
Warning: Can't perform a React state update on an unmounted component.
警告:无法对卸载的组件执行 React 状态更新。 This is a no-op, but it indicates a memory leak in your application.
这是一个空操作,但它表明您的应用程序中存在内存泄漏。 To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
要修复,请取消 useEffect 清理函数中的所有订阅和异步任务。
The idea is how to cancel the request on ComponentWillUnmount (or the cleanup function in useEffect
in my case) if it's not done already so that you won't have stale or unresolved requests in the background that will make your app slow.这个想法是如何取消对 ComponentWillUnmount 的请求(或者在我的例子中是
useEffect
中的清理函数),如果它还没有完成,这样你就不会在后台有陈旧或未解决的请求,这会使你的应用程序变慢。
It's a very common issue that a lot of people fall a victim to, and there's a lot of solutions out there, but not for this particular case (with dispatch and redux).这是一个非常普遍的问题,很多人都成为受害者,并且有很多解决方案,但不适用于这种特殊情况(使用 dispatch 和 redux)。
Some uses AbortController()
, and others use axios.CancelToken
but I'm not sure how to use either of them in my case.有些使用
AbortController()
,其他使用axios.CancelToken
但我不确定如何在我的情况下使用它们中的任何一个。
Try this for your action creator:为你的动作创建者试试这个:
export const asyncGetPostById = (postId: string) => async (dispatch: Function, getState: () => AppState) => {
try {
dispatch(startLoader());
const { data } = await axios.get(`api/posts/${postId}`);
dispatch(setPostDataInReducer(data));
} catch (error) {
console.log(error)
}
};
It's a subtle change, but with this action creator you're not actually returning anything (In TypeScript it would be void
)这是一个微妙的变化,但是有了这个动作创建者,你实际上并没有返回任何东西(在 TypeScript 中它会是
void
)
With a void
return, your dispatch
calls in the action creator will go straight to your reducer, but in your component nothing will be returned, so you shouldn't have to cleanup anything.使用
void
返回,您在动作创建器中的dispatch
调用将直接发送到您的减速器,但在您的组件中将不会返回任何内容,因此您不必清理任何内容。
Additionally, you should consider adding dispatch
to your useEffects
dependency array:此外,您应该考虑将
dispatch
添加到useEffects
依赖项数组中:
const dispatch = useDispatch();
useEffect(() => {
dispatch(asyncGetPostById(postId));
}, [dispatch]);
You must to create in your reducer a case
that clean the current state.您必须在减速器中创建一个清理当前状态的
case
。 And then in useEffect
you do like that然后在
useEffect
你喜欢那样
React.useEffect(()=> {
dispatch(your_action)
return () => dispatch(clean_data_action)
},[])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.