React嵌套路由问题:子组件跳转后父路由未激活加载
问题与解决方案
路由结构代码
index.js
const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <AuthFBContextProvider> <LangContextProvider> <BrowserRouter> <App /> </BrowserRouter> </LangContextProvider> </AuthFBContextProvider> );
App.js
return ( <Switch> {/* <Route path='/' exact> <Redirect to='/en' /> </Route> */} <Route path='/en'> <EnglishRouter /> </Route> <Route path="/fr"> <FrenchRouter/> </Route> <Route path='*'> <NotFound /> </Route> </Switch> );
EnglishRouter.js(父组件,仅在/en路径渲染)
<MainNavigation> <p>english route</p> <Switch> <Route path={path} exact> <MainPage /> </Route> <Route path={`${path}/promotions`} exact> {/* 对应路由 en/promotions */} <Promotions /> </Route> <Route path={`${path}/auth`}> {/* 对应路由 en/auth */} <AuthPage /> </Route> </Switch> </MainNavigation>)
AuthPage.js(子组件,在en/auth路径渲染)
<Router> <Switch> <Route path={`${path}/signup`} component={Signup} exact/> <Route path={`${path}/login`} component={Login} exact/> <Route path={`${path}/forgot-password`} component={ForgotPassword} exact/> </Switch> </Router>
Login.js
const Login = () => { const authFBCtx = useContext(AuthFBContext); const { path, url } = useRouteMatch() const history = useHistory(); const submitHandler = (event) => { event.preventDefault(); const enteredEmail = emailInputRef.current.value; const enteredPassword = passwordInputRef.current.value; authFBCtx.login(enteredEmail, enteredPassword); history.push('en/promotions') } return(...<form onSubmit={submitHandler}></form>) }
问题描述
登录后调用history.push('en/promotions'),URL显示正确但Promotions组件不加载;手动在AuthPage.js添加对应路由后组件能嵌套渲染,但父组件EnglishRouter的导航NavLink仍显示/en/auth为激活状态。需要实现跳转触发父组件路由更新,同步导航激活状态。
解决方案
1. 移除AuthPage中的多余<Router>组件
React Router的路由上下文是从上到下继承的,AuthPage已经被外层的BrowserRouter包裹,不需要再嵌套<Router>。多余的Router会创建独立的路由上下文,导致内部的路由操作无法同步到外层路由,这就是跳转后父组件路由不更新的核心原因。
修改后的AuthPage.js:
<Switch> <Route path={`${path}/signup`} component={Signup} exact/> <Route path={`${path}/login`} component={Login} exact/> <Route path={`${path}/forgot-password`} component={ForgotPassword} exact/> </Switch>
2. 使用正确的路径格式跳转
在Login.js中,建议使用绝对路径或者基于useRouteMatch返回的url构造目标路径,避免路径解析错误:
// 方式1:直接使用绝对路径 history.push('/en/promotions') // 方式2:基于当前语言路由的相对路径(适配多语言场景) const { url } = useRouteMatch(); history.push(`${url.split('/auth')[0]}/promotions`)
3. 修正导航NavLink的激活逻辑
检查MainNavigation中的NavLink,确保to属性为正确的绝对路径,若存在嵌套路由场景,可通过isActive自定义激活判断逻辑,确保父级导航在跳转后能正确取消激活:
<NavLink to="/en/auth" isActive={(match, location) => { // 仅当路径以/en/auth开头且不属于其他路由时激活 return location.pathname.startsWith('/en/auth') && !location.pathname.startsWith('/en/promotions'); }} > Auth </NavLink>
内容的提问来源于stack exchange,提问作者masafood
相关产品推荐
相关产品推荐

