React-Router-路线更改时的路线重新渲染组件

时间:2019-01-09 10:37:04

标签: reactjs typescript react-router-v4 react-loadable

在标记为重复之前,请正确阅读此内容,我向您保证,我已阅读并尝试了所有人关于stackoverflow和github上有关此问题的所有建议。

我的应用程序中有一条如下所示的路线;

<div>
        <Header compact={this.state.compact} impersonateUser={this.impersonateUser} users={users} organisations={this.props.organisations} user={user} logOut={this.logout} />
        <div className="container">
            {user && <Route path="/" component={() => <Routes userRole={user.Role} />} />}
        </div>
    {this.props.alerts.map((alert) =>
            <AlertContainer key={alert.Id} error={alert.Error} messageTitle={alert.Error ? alert.Message : "Alert"} messageBody={alert.Error ? undefined : alert.Message} />)
        }
    </div>

路由呈现Routes呈现一个打开用户角色的组件,并根据该角色懒加载正确的路由组件,该路由组件为主页呈现一个开关。简化如下所示。

import * as React from 'react';
import LoadingPage from '../../components/sharedPages/loadingPage/LoadingPage';
import * as Loadable from 'react-loadable';

export interface RoutesProps {
    userRole: string;
}

const Routes = ({ userRole }) => {

var RoleRoutesComponent: any = null;
switch (userRole) {
    case "Admin":
        RoleRoutesComponent = Loadable({
            loader: () => import('./systemAdminRoutes/SystemAdminRoutes'),
            loading: () => <LoadingPage />
        });
        break;
    default:
        break;
}

return (
    <div>
        <RoleRoutesComponent/> 
    </div>
);

}

export default Routes;

然后是路由部分

const SystemAdminRoutes = () => {

var key = "/";

return (
    <Switch>
        <Route key={key} exact path="/" component={HomePage} />
        <Route key={key} exact path="/home" component={HomePage} />
        <Route key={key} path="/second" component={SecondPage} />
        <Route key={key} path="/third" component={ThirdPage} />
        ...
        <Route key={key} component={NotFoundPage} />
    </Switch>
);
}

export default SystemAdminRoutes;

所以问题是每当用户从“ /”导航到“ / second”等时……应用重新渲染Routes,这意味着角色切换逻辑重新运行,特定于用户的路由被重新加载,重新呈现,页面状态丢失。

我尝试过的事情;

  • 我已经使用react-loadable和React.lazy()进行了尝试,但它具有相同的问题。
  • 我尝试过制作路线组件类
  • 为树上的所有路径赋予相同的键
  • 使用路径“ /”将所有组件呈现到交换机,但是仍然存在相同的问题。
  • 更改Route的组件prop进行渲染。
  • 将主应用程序的渲染方法更改为component={Routes}并通过redux获取道具
  • 我在应用程序组件中渲染主要路由组件的方式一定有问题,但是我很困惑,有人可以说清楚吗?还要注意,这与react-router的开关无关。

    编辑:我已经修改了我的旧测试项目之一以演示此错误,您可以从https://github.com/Trackerchum/route-bug-demo克隆存储库-克隆存储库后,只需在root目录中运行npm安装,然后启动npm。当重新渲染/重新安装Routes和SystemAdminRoutes时,我将其记录到控制台中

    编辑:我已经在GitHub上打开了一个与此有关的问题,可能是错误

    Route re-rendering component on every path change, despite path of "/"

    2 个答案:

    答案 0 :(得分:2)

    从开发人员那里发现了这种情况的直接发生(信贷Tim Tim)。路由每次都是重新渲染组件,因为它是一个匿名函数。这种情况在树的下方发生了两次,分别在下面的App和Routes中(在Loadable功能内)。

    <Route path="/" component={() => <Routes userRole={user.Role} />} />
    

    需要成为

    <Routes userRole={user.Role} />
    

    loader: () => import('./systemAdminRoutes/SystemAdminRoutes')
    

    基本上我的整个方法都需要重新考虑

    答案 1 :(得分:0)

    遇到了这个问题,解决方法如下:

    在组件中:

    import {useParams} from "react-router-dom";
        
    const {userRole: roleFromRoute} = useParams();
    const [userRole, setUserRole] = useState(null);
    
    
    useEffect(()=>{
        setUserRole(roleFromRoute);
    },[roleFromRoute]}
    

    在路线中:

    <Route path="/generic/:userRole" component={myComponent} />
    

    这会为角色设置一个带有参数的通用路由。

    在组件中 useParams 获取更改的参数,并且 useEffect 设置一个状态以触发渲染以及需要的任何业务逻辑。

    },[userRole]);