You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:36:04