React使用react-router-dom刷新页面后组件消失问题如何修复?
问题修复方案
该现象不属于预期行为,是React Router配置错误导致,核心问题有两个:
- 重复嵌套了BrowserRouter:整个React应用只需要在最外层(App.js)渲染一次BrowserRouter即可,你在Dialog组件内又嵌套了一层BrowserRouter,会导致两层路由上下文完全独立。点击NavLink时修改的是内层路由的状态,页面刷新后内层路由状态重置,且外层路由没有匹配
/messageOleg、/messageMax的规则,自然不会渲染对应内容。 - 嵌套路由路径不匹配:Dialog组件本身是在
/dialog路径下渲染的,内部的子路由路径没有和父路径对齐,刷新时外层路由无法匹配到对应规则,Dialog组件都不会被渲染,内部的子路由自然不会生效。
修复步骤
- 第一步:删除Dialog.jsx中BrowserRouter的引入和标签,移除多余的路由实例
- 第二步:调整Dialog内部的NavLink跳转路径和Route匹配路径,和父级路由路径对齐,子路由统一加上
/dialog前缀 - 第三步:确认App.js中
/dialog对应的Route没有加exact属性,否则嵌套路由无法正常匹配(你当前的App.js代码是符合要求的)
修改后Dialog.jsx代码示例
import React from 'react' import style from './Dialog.module.css' import MessageOleg from '../Messages/MessageOleg' import MessageMax from '../Messages/MessageMax' // 删掉BrowserRouter的引入,只保留Route和NavLink import { Route, NavLink } from 'react-router-dom' const Dialog = () => { return ( // 删掉外层的BrowserRouter标签 <div className={style.dialog}> <div className={style.users}> {/* 跳转路径加上/dialog前缀 */} <div className={style.user}> <NavLink to='/dialog/messageOleg'> Oleg </NavLink> </div><br /> <div className={style.user}> <NavLink to='/dialog/messageMax' >Max </NavLink> </div><br /> <div className={style.user}> Nata </div><br /> <div className={style.user}> Fuflo </div><br /> <div className={style.user}> Kiko </div><br /> </div> <hr /> {/* 匹配路径也加上/dialog前缀 */} <Route path='/dialog/messageOleg' component={MessageOleg} /> <Route path='/dialog/messageMax' component={MessageMax} /> </div> ) } export default Dialog;
可选优化
如果不想硬写父路径前缀,可以使用react-router-dom提供的useRouteMatch钩子动态获取父路由路径,后续修改父路由路径时无需同步调整子组件代码:
import { Route, NavLink, useRouteMatch } from 'react-router-dom' const Dialog = () => { const match = useRouteMatch(); return ( <div className={style.dialog}> <div className={style.users}> <div className={style.user}> <NavLink to={`${match.url}/messageOleg`}> Oleg </NavLink> </div><br /> <div className={style.user}> <NavLink to={`${match.url}/messageMax`} >Max </NavLink> </div><br /> {/* 其余代码不变 */} </div> <hr /> <Route path={`${match.path}/messageOleg`} component={MessageOleg} /> <Route path={`${match.path}/messageMax`} component={MessageMax} /> </div> ) }
问题场景参考
- 刷新前 *

- 刷新后 *

内容的提问来源于stack exchange,提问作者Maaas
相关产品推荐
相关产品推荐

