React-Router路由拆分至独立文件后重定向失效问题求助
解决路由拆分后登录重定向失效的问题
问题核心很明确:之前你在App.js里的路由逻辑能正常工作,是因为路由直接访问了组件内部的this.state.login状态,但把路由抽离到单独的route.js文件后,这个文件没办法获取到App组件的内部状态,所以登录判断和重定向逻辑就失效了。
下面给你两种可行的修复方案,你可以根据自己的需求选择:
方案一:将路由定义改为接收状态参数的函数
把route.js里的静态路由改成一个函数组件,让它接收isLogin作为参数,这样就能在路由逻辑里使用这个状态了:
修改route.js代码:
import React from 'react'; import Login from './Login'; import Register from './Register'; import Home from './Home'; import './style.css'; import { Route, Switch, Redirect } from 'react-router-dom'; // 改成函数组件,接收isLogin参数 const Routes = ({ isLogin }) => ( <Switch> <Route key="0" path="/" exact render={ () => isLogin ? <Home /> : <Redirect to="/login"/> } /> <Route key="1" path="/login" render={ props => <Login {...props} />} /> <Route key="2" path="/register" render={ props => <Register {...props} />} /> <Route key="3" path="/home" render={ () => isLogin ? <Home /> : <Redirect to="/login"/> } /> </Switch> ); export default Routes;
然后修改App.js,给路由组件传递isLogin状态:
import Routes from './route'; // 注意这里引入的是Routes组件,而非之前的静态routes变量 class App extends Component { state={ isLogin:false } render() { return ( <div className="App"> <Router> <Header/> <div className="container"> {/* 把App的登录状态传递给路由组件 */} <Routes isLogin={this.state.isLogin} /> </div> </Router> </div> ); } }
方案二:创建通用的受保护路由组件(更推荐)
这种方式更符合React组件复用的思想,把登录验证逻辑封装成一个通用的ProtectedRoute组件,以后所有需要登录才能访问的页面都可以直接复用这个组件:
首先创建ProtectedRoute.js文件:
import React from 'react'; import { Route, Redirect } from 'react-router-dom'; const ProtectedRoute = ({ isLogin, component: Component, ...rest }) => ( <Route {...rest} render={props => isLogin ? ( <Component {...props} /> ) : ( <Redirect to="/login" /> ) } /> ); export default ProtectedRoute;
然后修改route.js,使用这个受保护路由替代普通Route:
import React from 'react'; import Login from './Login'; import Register from './Register'; import Home from './Home'; import './style.css'; import { Route, Switch } from 'react-router-dom'; import ProtectedRoute from './ProtectedRoute'; const Routes = ({ isLogin }) => ( <Switch> <ProtectedRoute key="0" path="/" exact isLogin={isLogin} component={Home} /> <Route key="1" path="/login" render={ props => <Login {...props} />} /> <Route key="2" path="/register" render={ props => <Register {...props} />} /> <ProtectedRoute key="3" path="/home" isLogin={isLogin} component={Home} /> </Switch> ); export default Routes;
最后修改App.js,同样传递isLogin状态给Routes组件(和方案一的App.js修改一致):
import Routes from './route'; class App extends Component { state={ isLogin:false } render() { return ( <div className="App"> <Router> <Header/> <div className="container"> <Routes isLogin={this.state.isLogin} /> </div> </Router> </div> ); } }
这样修改后,不管路由怎么拆分,只要把登录状态传递给路由组件,重定向逻辑就能正常工作了。而且方案二的受保护路由可以在项目其他地方复用,扩展性更强。
内容的提问来源于stack exchange,提问作者Adesh Kumar
相关产品推荐
相关产品推荐

