React Router v4/Reactstrap路由异常:地址变更时页面未跳转
解决React Router同组件路由跳转不刷新的问题
我一眼就看出问题所在啦——你的两个路径/template/editor和/template/editor/3匹配的是同一个路由规则/template/editor/:id?,React Router为了性能优化,会复用已经挂载的EditorPage组件,不会重新触发组件的挂载流程(比如函数组件的初始渲染、类组件的componentDidMount),所以地址栏变了,但页面的初始化逻辑没重新执行,看起来就像没跳转一样。
给你几个简单的解决方案,按需选就行:
方案1:在组件内监听路由参数变化(推荐,函数组件版)
在EditorPage组件里用useParams获取参数,再用useEffect监听参数变化,触发对应的页面初始化逻辑:
import { useParams } from 'react-router-dom'; function EditorPage() { const { id } = useParams(); useEffect(() => { // 根据id是否存在,区分是新建模板还是编辑已有模板 if (id) { // 执行加载已有模板的逻辑 loadTemplateData(id); } else { // 初始化新模板的空白状态 initNewTemplateState(); } }, [id]); // 只要id变化,就重新执行这个逻辑 // ...组件其他代码 }
方案2:给Route添加key属性强制重新渲染
如果你不想修改组件内部逻辑,可以给路由组件加个key,让React认为不同路径是不同的组件实例,强制重新挂载:
<Route exact path="/template/editor/:id?" component={Authenticate(EditorPage)} key={window.location.pathname} />
这个方法简单粗暴,但会完全重新卸载再挂载组件,可能有轻微的性能开销,适合简单场景。
方案3:类组件的处理方式
如果你的EditorPage是类组件,可以用componentDidUpdate对比前后的路由参数,或者用withRouter包裹组件后监听location变化:
import { withRouter } from 'react-router-dom'; class EditorPage extends React.Component { componentDidMount() { this.setupPage(this.props.match.params.id); } componentDidUpdate(prevProps) { // 对比前后的id参数,变化了就重新初始化页面 if (prevProps.match.params.id !== this.props.match.params.id) { this.setupPage(this.props.match.params.id); } } setupPage(id) { if (id) { this.loadTemplate(id); } else { this.initNewTemplate(); } } // ...类组件其他方法 } // 用withRouter包裹,确保能拿到路由相关props export default withRouter(Authenticate(EditorPage));
本质上就是告诉React:路由参数变了,我需要重新执行页面的初始化逻辑啦~
内容的提问来源于stack exchange,提问作者SILENT
相关产品推荐
相关产品推荐

