[英]React-Router - Route re-rendering component on route change
Please read this properly before marking as duplicate, I assure you I've read and tried everything everyone suggests about this issue on stackoverflow and github.请在标记为重复之前正确阅读此内容,我向您保证我已经阅读并尝试了每个人在 stackoverflow 和 github 上提出的有关此问题的所有建议。
I have a route within my app rendered as below;我的应用程序中有一条路线呈现如下;
<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>
The route rendering Routes
renders a component that switches on the user role and lazy loads the correct routes component based on that role, that routes component renders a switch for the main pages.路由渲染
Routes
渲染一个组件,该组件在用户角色上切换,并根据该角色延迟加载正确的路由组件,该路由组件为主页呈现一个开关。 Simplified this looks like the below.简化后如下所示。
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;
And then the routes component然后路由组件
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;
So the issue is whenever the user navigates from "/" to "/second" etc... app re-renders Routes
, meaning the role switch logic is rerun, the user-specific routes are reloaded and re-rendered and state on pages is lost.所以问题是每当用户从“/”导航到“/second”等...应用程序重新渲染
Routes
,这意味着重新运行角色切换逻辑,重新加载和重新渲染用户特定的路由并在页面上显示丢失了。
Things I've tried;我尝试过的事情;
React.lazy()
and it has the same issue.React.lazy()
尝试过这个,它有同样的问题。component={Routes}
and getting props via reduxcomponent={Routes}
并通过 redux 获取道具There must be something wrong with the way I'm rendering the main routes component in the app component but I'm stumped, can anyone shed some light?我在应用程序组件中渲染主要路由组件的方式一定有问题,但我很困惑,有人能解释一下吗? Also note this has nothing to do with react-router's switch.
另请注意,这与 react-router 的开关无关。
EDIT: I've modified one of my old test project to demonstrate this bug, you can clone the repo from https://github.com/Trackerchum/route-bug-demo - once the repo's cloned just run an npm install in root dir and npm start.编辑:我已经修改了我的一个旧测试项目来演示这个错误,你可以从https://github.com/Trackerchum/route-bug-demo克隆 repo - 一旦 repo 被克隆,只需在 root 中运行 npm install dir 和 npm start。 I've got it logging to console when the Routes and SystemAdminRoutes are re-rendered/remounted
当 Routes 和 SystemAdminRoutes 重新渲染/重新安装时,我已将其记录到控制台
EDIT: I've opened an issue about this on GitHub, possible bug编辑:我已经在 GitHub 上打开了一个关于这个的问题,可能是错误
Route re-rendering component on every path change, despite path of "/"尽管路径为“/”,但在每次路径更改时路由重新渲染组件
Found the reason this is happening straight from a developer (credit Tim Dorr).直接从开发人员那里找到了发生这种情况的原因(感谢 Tim Dorr)。 The route is re-rendering the component every time because it is an anonymous function.
路由每次都重新渲染组件,因为它是一个匿名函数。 This happens twice down the tree, both in App and Routes (within Loadable function), below respectively.
这在树下发生两次,分别在 App 和 Routes(在 Loadable 函数内),分别如下。
<Route path="/" component={() => <Routes userRole={user.Role} />} />
needs to be需要是
<Routes userRole={user.Role} />
and和
loader: () => import('./systemAdminRoutes/SystemAdminRoutes')
Basically my whole approach needs to be rethought基本上我的整个方法需要重新思考
EDIT: I eventually fixed this by using the render method on route:编辑:我最终通过在路由上使用渲染方法解决了这个问题:
<Route path="/" render={() => <Routes userRole={user.Role} />} />
Bumped into this problem and solved it like this:碰到这个问题并解决它是这样的:
In the component:在组件中:
import {useParams} from "react-router-dom";
const {userRole: roleFromRoute} = useParams();
const [userRole, setUserRole] = useState(null);
useEffect(()=>{
setUserRole(roleFromRoute);
},[roleFromRoute]}
In the routes:在路线中:
<Route path="/generic/:userRole" component={myComponent} />
This sets up a generic route with a parameter for the role.这将使用角色的参数设置通用路由。
In the component useParams picks up the changed parameter und the useEffect sets a state to trigger the render and whatever busines logic is needed.在组件中 useParams 获取更改的参数,并且 useEffect 设置一个状态以触发渲染以及需要的任何业务逻辑。
},[userRole]); },[用户角色]);
Just put the "/" in the end and put the other routes above it.只需将“/”放在最后并将其他路线放在其上方。 Basically it's matching the first available option, so it matches "/" every time.
基本上它匹配第一个可用选项,所以它每次都匹配“/”。
<Switch>
<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} exact path="/" component={HomePage} />
<Route key={key} component={NotFoundPage} />
</Switch>
OR
<Switch>
<Route path="/second" component={SecondPage} />
<Route exact path="/" component={HomePage} />
<Route path="*" component={NotFound} />
</Switch>
Reorder like this, it will start working.像这样重新排序,它将开始工作。 Simple :)
简单的 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.