React Router DOM v6替换旧版match/location路由props的方法
React Router DOM v6 替代v4生命周期路由监听方案
React Router DOM v6 不再自动向类组件注入match、location这类路由属性,所有路由相关值都需要通过官方提供的Hook获取,类组件可以通过高阶组件封装,把路由值转为props传入,后续的变更对比逻辑和v4写法基本一致。
第一步:封装高阶组件注入路由属性
类组件不能直接调用Hook,先封装一个通用的withRouter高阶组件,把需要用到的路由值透传到组件props中:
import { useLocation, useParams, useMatch } from 'react-router-dom'; const withRouter = (WrappedComponent) => { return function RouterWrapper(props) { const location = useLocation(); const params = useParams(); // 传入的路径规则要和当前组件匹配的路由规则保持一致 // 比如组件挂载在/*路由下就传"/*",挂载在/docs/*下就传"/docs/*" const match = useMatch("/*"); return <WrappedComponent {...props} location={location} params={params} match={match} />; }; }; // 导出时用withRouter包裹你的类组件即可 // export default withRouter(YourPageComponent)
第二步:替换原有生命周期逻辑
包裹完成后,类组件的props里就能拿到和v4语义一致的路由相关字段,直接调整参数名即可复用原有判断逻辑。
监听路由参数变化执行业务代码
v4中通配符*匹配到的路径段存在match.params[0]中,v6调整为存在match.params["*"]字段下,判断逻辑如下:
componentDidUpdate(prevProps) { if (prevProps.match.params["*"] !== this.props.match.params["*"]) { // 原有业务逻辑直接放在这里即可 } }
如果你监听的是具名路由参数(比如路由规则为/article/:id中的id),直接从params中取对应字段对比即可:
componentDidUpdate(prevProps) { if (prevProps.params.id !== this.props.params.id) { // 对应参数变化后的业务逻辑 } }
监听路径变化触发内容加载
这部分逻辑和v4写法完全一致,直接对比前后location.pathname的值即可:
componentDidUpdate(prevProps) { if (this.props.location.pathname !== prevProps.location.pathname) { this.loadContent(); } }
函数组件简化写法参考
如果使用函数组件开发,不需要手动对比前后props,直接通过useEffect监听路由值变化即可,代码更简洁:
import { useEffect } from 'react'; import { useLocation, useParams } from 'react-router-dom'; function YourPageComponent() { const location = useLocation(); const params = useParams(); // 监听通配符路径变化 useEffect(() => { // 参数变化后的业务逻辑 }, [params["*"]]); // 监听pathname变化加载内容 useEffect(() => { loadContent(); }, [location.pathname]); // 组件其余代码 }
内容的提问来源于stack exchange,提问作者Martinchety
相关产品推荐
相关产品推荐

