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

时间:2020-09-17 19:09:50

标签: reactjs redux react-hooks next.js use-effect

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

2 个答案:

答案 0 :(得分:0)

为您的动作创建者尝试一下:

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调用将直接转到化简器,但是在您的组件中将不返回任何内容,因此您不必清理任何内容。 / p>

编辑:

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

const dispatch = useDispatch();

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

答案 1 :(得分:0)

必须在化简器中创建一个case来清除当前状态。然后在useEffect中您确实喜欢

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