React中点击角色按钮重定向到对应门户组件失败如何解决?
问题根源
- 状态管理错误:
userState目前仅在Nav组件内部初始化,只接收App传入的初始值/,后续无法被外部组件更新。你在注册页点击事件中返回Nav组件的写法完全无效,事件函数的返回值不会被插入到DOM树中替换已渲染的组件。 - 多Router冲突:你在
Nav组件的三个渲染分支中分别实例化了独立的Router,导致路由上下文不互通,history.push方法自然无法生效,整个React应用全局只需要一个顶层Router即可。 - 重复冗余代码:管理员和学生身份的路由配置大量重复,可合并简化降低维护成本。
修复步骤
步骤1:状态提升至App组件,统一管理用户身份
修改App.js代码:
// 从react-router-dom引入Router import { BrowserRouter as Router } from 'react-router-dom'; class App extends React.Component{ constructor(props) { super(props); this.state = { userState: "/" // 全局存储用户身份状态 } } // 提供更新用户身份的方法,传给子组件调用 setUserState = (role) => { this.setState({ userState: role }); } render(){ return( <Router> {/* 全局仅需要这一个Router */} <div className="container"> <Nav userState={this.state.userState} setUserState={this.setUserState} /> <Footer /> </div> </Router> ); } }
步骤2:修改Nav组件,删除内部状态和重复Router
修改Nav组件代码:
class Nav extends React.Component { // 删除内部维护的userState,直接使用props传入的参数 render() { const { userState, setUserState } = this.props; if (userState == "/") { return ( <Switch> <Route exact path="/"> <h2>Bow Valley College- Course Registration Portal</h2> <Login /> {/* 把setUserState方法传给Register组件供点击事件调用 */} <Register setUserState={setUserState} /> </Route> </Switch> ) } if (userState == "admin") { return ( <> <AdminRender /> <Switch> {/* 管理员专属路由 */} <Route exact path="/adminHome" component={Search} /> <Route path="/search" component={Search} /> <Route path="/delete" component={Delete} /> <Route path="/add" component={Add} /> <Route path="/list" component={List} /> <Route path="/forms" component={Forms} /> {/* 公共路由 */} <Route path="/studentHome" exact component={EnrolledCourses} /> <Route path="/studentAddCourses" component={AddCourses} /> <Route path="/studentContactForm" component={ContactForm} /> <Route path="/register" render={(props) => <Register {...props} setUserState={setUserState} />} /> </Switch> </> ) } else if (userState == "student") { return ( <> <StudentRender /> <Switch> {/* 学生专属路由 */} <Route path="/studentHome" exact component={EnrolledCourses} /> <Route path="/studentAddCourses" component={AddCourses} /> <Route path="/studentContactForm" component={ContactForm} /> {/* 公共路由 */} <Route exact path="/adminHome" component={Search} /> <Route path="/search" component={Search} /> <Route path="/delete" component={Delete} /> <Route path="/add" component={Add} /> <Route path="/list" component={List} /> <Route path="/forms" component={Forms} /> <Route path="/register" render={(props) => <Register {...props} setUserState={setUserState} />} /> </Switch> </> ) } } }
步骤3:修改注册页点击事件逻辑
修改adminSubmitEvent方法,无需返回JSX,直接调用传入的setUserState更新全局身份,再跳转到对应页面即可:
// 如果拿不到history属性,先引入withRouter包裹Register组件 import { withRouter } from 'react-router-dom'; adminSubmitEvent = (event) => { event.preventDefault(); // 执行注册校验、数据入库逻辑 // 更新全局用户身份为admin this.props.setUserState("admin"); // 跳转到管理员主页 this.props.history.push("/adminHome"); } // 导出Register时用withRouter包裹,即可正常获取history属性 export default withRouter(Register);
内容的提问来源于stack exchange,提问作者faizan shafiq
相关产品推荐
相关产品推荐

