首页 > 解决方案 > 在自定义快速路由中使用 useEffect 时无法执行反应状态更新错误

问题描述

我的自定义快递路线有问题。每次我通过自定义路由组件更改页面时,我都会收到一个 react no-op 错误:
警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 useEffect 清理函数中取消所有订阅和异步任务。

这是我的自定义路由组件/处理程序:

import React from 'react';
import { Route } from 'react-router-dom';

import { AuthenticationContext } from '../../contexts/authentication/context';

import Unauthorized from '../Unauthorized';

import axios from 'axios';

const ProtectedRoute = ({ component: Component, redirect: Redirect, contextProvider: ContextProvider, path, ...routeProps }) => {

  const { authenticationState: {isAuthenticated, isFetchingTheUser, currentUser} } = React.useContext(AuthenticationContext)

  const [authorized, setAuthorized] = React.useState(['Admin']);
  const [isFetchingAuthorizations, setIsFetchingAuthorizations] = React.useState(false);

  React.useEffect(() => {
    console.log("useEffect from protected route")
    setIsFetchingAuthorizations(true);
    axios.get(`${global.REST_API_ADDR}/api/pages/${encodeURIComponent(path)}`)
    .then((response) => {
      setAuthorized(response.data.authorized);
      setIsFetchingAuthorizations(false);
    })
    .catch((error) => {
      setIsFetchingAuthorizations(false);
      console.log("Protected route use Effect error : ", error);
    })
  }, [path])

  return (
    <Route {...routeProps}
      render={ props => {

        if(isFetchingTheUser || isFetchingAuthorizations) return <div>Chargement...</div>

        if(isAuthenticated && authorized.includes(currentUser.rank)){
          return ContextProvider ? <ContextProvider><Component {...props} /></ContextProvider> : <Component {...props} />
        }else if(isAuthenticated && !authorized.includes(currentUser.rank)) {
          return <Unauthorized {...props} />;
        }
        else{
          return <Redirect {...props}/>;
        }
    }}/>
  );

};

export default ProtectedRoute;

如果使用 useEffect() 删除部分,我不再在控制台中收到警告,但我确实需要这个钩子来检查用户是否有权访问此页面

有人可以启发我吗?

提前致谢

编辑1:我尝试创建一个空组件并通过我的相同自定义路由(ProtectedRoute)访问它并且没有警告,这个“空组件”没有任何useEffect,它似乎是其他组件的问题。 ..因此,当我尝试访问其中包含 useEffect 的组件时,我收到了此警告...

编辑 2:通过进一步测试,我可以肯定地确认问题来自我的 ProtectedRoute 组件中的 useEffect,如果我手动设置“授权”数组和“isFetchingAuthorizations”它工作正常。问题似乎来自http请求中的setter(如果我只评论setter,它也可以正常工作......)

编辑 3:我在我的空组件中添加了一个 useEffect 来获取我的所有用户并显示它,它像所有其他组件一样抛出警告。我想问题出在组件中有一个 useEffect ......

编辑4:我在我的空组件的useEffect中添加了一个console.log,似乎即使没有返回组件,也会触发useEffect!这可能是这里的问题!

编辑 5:问题似乎来自每个路由之间保持“授权”状态这一事实,因此当用户要求新路由时,“自动”状态由前一页授权数组填充......不知道如何修复它,我正在尝试在路线服务后清空它......如果没有人有一些提示

标签: reactjsexpressreact-hooks

解决方案


对于您的情况,我有一个建议,如下所示:

useEffect(() => {
   let didCancel = false; // to trigger handle clean up
   const fetchData = async () => {
      try {
          const result = await .get(`${global.REST_API_ADDR}/api/pages/${encodeURIComponent(path)}`);
          if (!didCancel) {
              setAuthorized(result...);
              setIsFetchingAuthorizations(result...);
          }
      } catch (error) {
          if (!didCancel) {
              setIsFetchingAuthorizations(result...);
          }
      }
   };
   fetchData()
   return {
      didCancel = true; // clean up useEffect
   }
})

希望能帮到你!


推荐阅读