react-router-dom v6类组件路由间传值时PubSub不生效如何解决
问题根因
你当前PubSub传参失效的核心原因是发布动作的执行时机早于订阅动作:点击Link时首先触发onClick执行PubSub.publish,此时目标路由对应的ProductDetails组件还未完成挂载(路由跳转流程尚未执行完成,组件实例还未初始化),componentDidMount中的订阅逻辑还没运行,自然无法接收到发布的事件。
推荐解决方案:使用react-router-dom v6原生路由state传参
不需要引入第三方PubSub库,v6本身支持在路由跳转时携带任意类型的隐式参数,类组件可以通过封装HOC的方式兼容获取路由属性。
1. 跳转时传递参数
修改ProductHome组件中的Link配置,直接在to属性中传入带state的配置对象即可:
import React, { Component } from 'react' import { Link } from 'react-router-dom'; export default class ProductHome extends Component { // 不需要pubProduct相关的发布逻辑 render(){ const product = {a: 1} return ( <Link to={{ pathname: '/product/details', state: { product } // 此处可传入任意需要传递的非敏感数据 }} > Details </Link> ) } }
2. 类组件接收参数
react-router-dom v6移除了官方的withRouter HOC,你可以自行封装一个兼容层,给类组件注入路由相关属性:
首先新建withRouter.js封装HOC:
import { useLocation, useNavigate, useParams } from 'react-router-dom'; export function withRouter(WrapperComponent) { return (props) => { const location = useLocation(); const navigate = useNavigate(); const params = useParams(); return <WrapperComponent {...props} router={{ location, navigate, params }} />; }; }
修改ProductDetails组件,使用封装的HOC包裹后直接取参数:
import React, { Component } from 'react' import { withRouter } from './withRouter'; class ProductDetails extends Component { state = { product: {} } componentDidMount() { // 从路由属性中获取传递的参数 const { product } = this.props.router.location.state || {}; this.setState({ product }); } render(){/* 原有逻辑 */} } // 导出时用withRouter包裹组件 export default withRouter(ProductDetails);
可选方案:PubSub适配修正
如果一定要使用PubSub实现传参,你需要调整执行逻辑保证订阅先于发布:可以把Link替换为普通按钮,点击后先跳转路由,待目标组件挂载完成后再触发发布,或者将临时数据存入sessionStorage,目标组件挂载后读取并清除缓存。该方案额外逻辑多、稳定性不如原生路由传参,不推荐使用。
内容的提问来源于stack exchange,提问作者hwu2016
相关产品推荐
相关产品推荐

