繁体   English   中英

如何清理 useEffect 中的 Redux“useDispatch”动作?

[英]How to clean up a Redux "useDispatch" action inside useEffect?

我为此找到了很多示例,但没有一个使用 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但我不确定如何在我的情况下使用它们中的任何一个。

为你的动作创建者试试这个:

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

这是一个微妙的变化,但是有了这个动作创建者,你实际上并没有返回任何东西(在 TypeScript 中它会是void

使用void返回,您在动作创建器中的dispatch调用将直接发送到您的减速器,但在您的组件中将不会返回任何内容,因此您不必清理任何内容。

编辑:

此外,您应该考虑将dispatch添加到useEffects依赖项数组中:

const dispatch = useDispatch();

useEffect(() => {
    dispatch(asyncGetPostById(postId));
}, [dispatch]);

您必须在减速器中创建一个清理当前状态的case 然后在useEffect你喜欢那样

React.useEffect(()=> {
 dispatch(your_action)
 return () => dispatch(clean_data_action)
},[])
 

暂无
暂无

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

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