React-Router - 路由更改时路由重新渲染组件
React-Router - Route re-rendering component on route change
请在标记为重复之前正确阅读此内容,我向你保证我已经阅读并尝试了每个人在 Whosebug 和 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 组件道具。
将主应用程序渲染方法更改为 component={Routes}
并通过 redux 获取道具
我在应用程序组件中呈现主要路由组件的方式一定有问题,但我很困惑,有人能解释一下吗?另请注意,这与 react-router 的开关无关。
编辑:我已经修改了我的一个旧测试项目来演示这个错误,你可以从 https://github.com/Trackerchum/route-bug-demo 克隆 repo - 一旦 repo 被克隆 运行 根目录中的 npm 安装和 npm 开始。当 Routes 和 SystemAdminRoutes 为 re-rendered/remounted
时,我已将其记录到控制台
编辑:我已经在 GitHub 上打开了一个关于此的问题,可能是错误
Route re-rendering component on every path change, despite path of "/"
直接从开发人员那里找到了发生这种情况的原因(感谢 Tim Dorr)。路由每次都重新渲染组件,因为它是一个匿名函数。这在树下发生了两次,分别在下面的 App 和 Routes(在 Loadable 函数内)中。
<Route path="/" component={() => <Routes userRole={user.Role} />} />
需要
<Routes userRole={user.Role} />
和
loader: () => import('./systemAdminRoutes/SystemAdminRoutes')
基本上我的整个方法都需要重新考虑
编辑:我最终通过在路线上使用渲染方法解决了这个问题:
<Route path="/" render={() => <Routes userRole={user.Role} />} />
遇到这个问题,然后这样解决:
在组件中:
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 设置一个状态来触发渲染和任何需要的业务逻辑。
},[用户角色]);
把“/”放在最后,其他路由放在上面就行了。
基本上它匹配第一个可用选项,所以它每次都匹配“/”。
<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>
像这样重新排序,它将开始工作。
简单:)
请在标记为重复之前正确阅读此内容,我向你保证我已经阅读并尝试了每个人在 Whosebug 和 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.lazy()
试过了,它有同样的问题。component={Routes}
并通过 redux 获取道具我在应用程序组件中呈现主要路由组件的方式一定有问题,但我很困惑,有人能解释一下吗?另请注意,这与 react-router 的开关无关。
编辑:我已经修改了我的一个旧测试项目来演示这个错误,你可以从 https://github.com/Trackerchum/route-bug-demo 克隆 repo - 一旦 repo 被克隆 运行 根目录中的 npm 安装和 npm 开始。当 Routes 和 SystemAdminRoutes 为 re-rendered/remounted
时,我已将其记录到控制台编辑:我已经在 GitHub 上打开了一个关于此的问题,可能是错误
Route re-rendering component on every path change, despite path of "/"
直接从开发人员那里找到了发生这种情况的原因(感谢 Tim Dorr)。路由每次都重新渲染组件,因为它是一个匿名函数。这在树下发生了两次,分别在下面的 App 和 Routes(在 Loadable 函数内)中。
<Route path="/" component={() => <Routes userRole={user.Role} />} />
需要
<Routes userRole={user.Role} />
和
loader: () => import('./systemAdminRoutes/SystemAdminRoutes')
基本上我的整个方法都需要重新考虑
编辑:我最终通过在路线上使用渲染方法解决了这个问题:
<Route path="/" render={() => <Routes userRole={user.Role} />} />
遇到这个问题,然后这样解决:
在组件中:
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 设置一个状态来触发渲染和任何需要的业务逻辑。
},[用户角色]);
把“/”放在最后,其他路由放在上面就行了。 基本上它匹配第一个可用选项,所以它每次都匹配“/”。
<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>
像这样重新排序,它将开始工作。 简单:)