簡體   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