简体   繁体   English

我得到错误:即使我创建了清理,也无法对未安装的组件执行 React state 更新

[英]I get Error: Can't perform a React state update on an unmounted component even though i created cleanup

An error keeps bothering me on my app says一个错误一直困扰着我的应用程序说

Warning: Can't perform a React state update on an unmounted component. 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.

I do declare a useEffect in my Context so that I can have a realtime data storing and getting for my app.我确实在我的上下文中声明了一个 useEffect,以便我可以为我的应用程序存储和获取实时数据。

Here is my code in Context;这是我在上下文中的代码;

const FetchProvider = ({ children }) => {
    const [userList, setUserList] = useState([]);
    const [teamList, setTeamList] = useState([]);

    const authContext = useContext(AuthContext);
    const authAxios = axios.create({
        baseURL: process.env.REACT_APP_API_URL,
    });

    useEffect(() => {
        let isCancelled = false;
        if (
            authContext.isAuthenticated &&
            authContext.authState.userInfo !== null
        ) {
            const getUsers = async () => {
                try {
                    const users = await authAxios.get('/admin/get-all-users');
                    if (!isCancelled) {
                        setUserList(users.data);
                    }
                } catch (error) {
                    if (!isCancelled) {
                        console.log(error);
                    }
                }
            };

            const getTeams = async () => {
                try {
                    const teams = await authAxios.get('/get-all-teams');
                    if (!isCancelled) {
                        setTeamList(teams.data);
                    }
                } catch (error) {
                    if (!isCancelled) {
                        console.log(error);
                    }
                }
            };
            getUsers();
            getTeams();
        }
        return () => {
            isCancelled = true;
        };
    }, [authAxios, authContext]);

    return (
        <Provider
            value={{
                authAxios,
                userList,
                setUserList,
                teamList,
                setTeamList,
            }}
        >
            {children}
        </Provider>
    );
};

And I get this error in my Login.jsx and in my even though I don't declare useEffect in submitting and declaring it in.我在我的 Login.jsx 和我的 Login.jsx 中得到了这个错误,即使我在提交和声明它时没有声明 useEffect 。

Here is my code;这是我的代码;

const submitCredentials = async (credentials, resetForm) => {
        try {
            setLoginLoading(true);
            const { data } = await publicFetch.post('signin', credentials);
            authContext.setAuthState(data);
            setSignupSuccess(data.message);
            setSignupError('');
            setOpen(true);
            setTimeout(() => {
                setLoginLoading(false);
                setredirectOnlogin(true);
                resetForm(true);
            }, 400);
        } catch (error) {
            setLoginLoading(false);
            const { data } = error.response;
            setSignupError(data.message);
            setSignupSuccess('');
            setOpen(true);
        }
        return setLoginLoading(false);
    };

And I have tried many ways the internet has offered to fix this up but unfortunately it does not fix my problem.我已经尝试了互联网提供的许多方法来解决这个问题,但不幸的是它并没有解决我的问题。

I do have useEffect in my UsersTable.jsx and TeamTables.jsx.我的 UsersTable.jsx 和 TeamTables.jsx 中确实有 useEffect。

Here is my code in UsersTable.jsx;这是我在 UsersTable.jsx 中的代码;

useEffect(() => {
        let isCancelled = false;
        const getUsers = async () => {
            try {
                const users = await fetchContext.authAxios.get('/admin/get-all-users');
                setIsLoaded(true);
                if (isLoaded === true) {
                    if (!isCancelled) {
                        fetchContext.setUserList(users.data);
                    }
                }
                return () => {
                    isCancelled = true;
                };
            } catch (error) {
                if (!isCancelled) {
                    console.log(error);
                }
            }
        };
        getUsers();
        return () => {
            isCancelled = true;
        };
    }, [fetchContext, isLoaded]);

Here is my useEffect code in my TeamTable.jsx;这是我的 TeamTable.jsx 中的 useEffect 代码;

useEffect(() => {
        let isCancelled = false;
        const getTeams = async () => {
            try {
                const teams = await fetchContext.authAxios.get('get-all-teams');
                setIsLoaded(true);
                if (isLoaded === true) {
                    if (!isCancelled) {
                        fetchContext.setTeamList(teams.data);
                    }
                }
            } catch (error) {
                if (!isCancelled) {
                    console.log(error);
                }
            }
        };
        getTeams();
        return () => {
            isCancelled = true;
        };
    }, [fetchContext, isLoaded]);

The isLoaded is used as an AJAX isLoaded 用作 AJAX

Well, you can use the React recommended way to fix this issue.好吧,你可以使用 React 推荐的方法来解决这个问题。 All you need to do is wrap your api call within makeCancellable method and cancel them when your component is unmounting.您需要做的就是将 api 调用包装在 makeCancellable 方法中,并在卸载组件时取消它们。

Ref: https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html参考: https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html

To do that create为此创建

const makeCancelable = (promise) => {
  let isCancelled = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then(
      val => isCancelled ? reject({isCanceled: true}) : resolve(val),
      error => isCancelled ? reject({isCanceled: true}) : reject(error)
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      isCancelled = true;
    },
  };
};

create a variable for the request outside your useEffect为您的useEffect之外的请求创建一个变量

let fetchTeamsRequest = null;

and updated your useEffect function like below.并更新了您的useEffect function,如下所示。

useEffect(() => {
    const getTeams = async () => {
        if (fetchTeamsRequest) {
            try {
                await fetchTeamsRequest.promise;

                return;
            } catch (error) {
                return;
            }
        }

        fetchTeamsRequest = makeCancellable(fetchContext.authAxios.get('get-all-teams'));

        try {
            const teams = await fetchTeamsRequest.promise;

            fetchTeamsRequest = null;

            setIsLoaded(true);

            if (isLoaded === true) {
                if (!fetchTeamsRequest.isCancelled) {
                    fetchContext.setTeamList(teams.data);
                }
            }
        } catch (error) {
            if (!fetchTeamsRequest.isCancelled) {
                fetchTeamsRequest = null;
                console.log(error);
            }
        }
    };

    getTeams();

    return () => {
        if (fetchTeamsRequest) {
            fetchTeamsRequest.cancel();
        }
    };
}, [fetchContext, isLoaded]);

暂无
暂无

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

相关问题 当我使用 Async/Await 时,我收到以下警告:Can't perform a React state update on an unmounted component - When i use Async/Await i get the warning of : Can't perform a React state update on an unmounted component React Can't perform a React state update on an unmounted component error - React Can't perform a React state update on an unmounted component error “无法在未安装的组件上执行 React state 更新”错误 - The “Can't perform a React state update on an unmounted component” error 修复“无法对卸载的组件执行 React 状态更新”错误 - Fix "Can't perform a React state update on an unmounted component" error 在useEffect清理函数执行之前获取“无法对卸载的组件执行React状态更新” - Getting 'Can't perform a React state update on an unmounted component' before useEffect cleanup function executes 警告:无法对未安装的组件执行 React state 更新。 使用效果清理 function - Warning: Can't perform a React state update on an unmounted component. useEffect cleanup function 构建一个反应应用程序但收到一条我找不到的错误消息:警告:无法在未安装的组件上执行 React state 更新 - Building a react app but getting an error message that I can't locate: Warning: Can't perform a React state update on an unmounted component 为什么我收到以下 React Native 警告:Can&#39;t perform a React state update on an unmounted component - Why am I getting the following React Native warning: Can't perform a React state update on an unmounted component 我不断收到 Can't perform a React state update on an unmounted component - I keep getting Can't perform a React state update on an unmounted component React - 无法在未安装的组件上执行 React state 更新 - React - Can't perform a React state update on an unmounted component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM