React.js中如何实现条件路由?附代码示例求助
在React.js中实现条件路由(保护路由)
Hey there! 要实现你说的这种条件路由(也叫保护路由),核心思路就是创建一个自定义的路由组件,用来校验用户的登录状态——只有当用户已登录时,才允许访问受保护的页面(比如你的Welcome页),否则直接重定向到登录页面。下面我结合你的现有代码一步步修改:
1. 先修正现有代码里的小问题
首先看你的Header.js,Link的to属性应该传路径字符串,而不是组件本身;另外React元素的class属性要写成className(不然会报错),修正后的Header.js如下:
import React, { Component } from 'react'; import { Link } from 'react-router-dom'; class Header extends Component{ render(){ return( <div> <nav className="navbar navbar-default"> <div className="container-fluid"> <ul className="nav navbar-nav"> <li><Link to="/login">Login</Link></li> <li><Link to="/signup">SignUp</Link></li> </ul> </div> </nav> </div> ); } } export default Header;
2. 创建受保护路由组件(ProtectedRoute)
我们需要写一个自定义路由组件,用来检查用户的登录状态。这里用localStorage存储登录状态(简单易上手,后续用Redux/Context管理状态逻辑类似):
新建ProtectedRoute.js文件:
import React from 'react'; import { Route, Redirect } from 'react-router-dom'; class ProtectedRoute extends Component { render() { // 检查localStorage中的登录标记 const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'; const { component: Component, ...rest } = this.props; return ( <Route {...rest} render={(props) => { // 已登录则渲染目标组件,否则重定向到登录页 return isLoggedIn ? <Component {...props} /> : <Redirect to="/login" />; }} /> ); } } export default ProtectedRoute;
3. 修改AllRoutes,替换为受保护路由
把原来的Welcome路由换成我们刚写的ProtectedRoute,同时统一路径大小写(改成小写/welcome更规范):
import React, { Component } from 'react'; import { Switch, Route } from 'react-router-dom'; import Login from './Login'; import SignUp from './SignUp'; import Welcome from './Welcome'; import ProtectedRoute from './ProtectedRoute'; // 引入保护路由 class AllRoutes extends Component{ render(){ return( <Switch> <Route exact path="/login" component={Login} /> <Route exact path="/signup" component={SignUp} /> {/* 替换为受保护路由 */} <ProtectedRoute exact path="/welcome" component={Welcome} /> </Switch> ); } } export default AllRoutes;
4. 完善Login组件的登录逻辑
你没提供Login组件代码,这里写一个简单示例,实现登录成功后设置登录状态并跳转:
Login.js:
import React, { Component } from 'react'; import { Redirect } from 'react-router-dom'; class Login extends Component { state = { username: '', password: '', redirectToWelcome: false }; handleInputChange = (e) => { const { name, value } = e.target; this.setState({ [name]: value }); }; handleLogin = (e) => { e.preventDefault(); // 模拟凭证校验,可替换为真实API请求 const { username, password } = this.state; if (username === 'admin' && password === '123456') { // 登录成功,存储状态到localStorage localStorage.setItem('isLoggedIn', 'true'); this.setState({ redirectToWelcome: true }); } else { alert('用户名或密码错误!'); } }; render() { if (this.state.redirectToWelcome) { return <Redirect to="/welcome" />; } return ( <div style={{ margin: '20px' }}> <h3>Login</h3> <form onSubmit={this.handleLogin}> <div> <label>用户名:</label> <input type="text" name="username" value={this.state.username} onChange={this.handleInputChange} required /> </div> <div> <label>密码:</label> <input type="password" name="password" value={this.state.password} onChange={this.handleInputChange} required /> </div> <button type="submit">登录</button> </form> </div> ); } } export default Login;
5. 补充退出登录逻辑(可选)
在Welcome页添加退出按钮,清除登录状态并跳转回登录页:
修改Welcome.js:
import React, { Component } from 'react'; import { Redirect } from 'react-router-dom'; class Welcome extends Component{ state = { redirectToLogin: false }; handleLogout = () => { // 清除登录状态 localStorage.removeItem('isLoggedIn'); this.setState({ redirectToLogin: true }); }; render(){ if (this.state.redirectToLogin) { return <Redirect to="/login" />; } return( <div> <h2>Welcome to MainPage..</h2> <button onClick={this.handleLogout}>退出登录</button> </div> ); } } export default Welcome;
测试效果
现在你可以验证:
- 直接访问
localhost:8080/welcome会自动跳转到登录页 - 输入正确凭证(admin/123456)登录后,可正常进入Welcome页
- 点击退出登录后,再次访问welcome页会被拦截
这样就实现了你需要的条件路由功能啦!
内容的提问来源于stack exchange,提问作者Srikanth Gowda
相关产品推荐
相关产品推荐

