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

StreamEdit组件props为空,无法获取match.params.id的问题

问题:React Router v6 类组件无法获取路由参数 match.params.id

我在App.js中配置了带参数的路由/streams/edit/:id,但StreamEdit类组件里拿不到this.props.match.params.id,打印props发现是空的,期望能正常获取路由ID。

App.js 代码:

import { Route, Routes } from 'react-router-dom';
import { unstable_HistoryRouter as HistoryRouter } from "react-router-dom";
import './App.css';
//,BrowserRouter as Router

const App = () => {
  return (
    <div id='app_div'>
      <HistoryRouter history={history}>
        <Header />
        <Routes>
          <Route path='/' exact Component={StreamList} />
          <Route path='/streams/new' Component={StreamCreate} />
          <Route path='/streams/edit/:id' Component={StreamEdit}  />
          <Route path='/streams/delete' Component={StreamDelete} />
          <Route path='/streams/show' Component={StreamShow} />
        </Routes>
      </HistoryRouter>
    </div>
  );
};

export default App;

StreamEdit 组件代码:

import React from "react";
import { connect } from "react-redux";
import { fetchStream } from '../../actions';

class StreamEdit extends React.Component{
  componentDidMount() {
    this.props.fetchStream(this.props.match.params.id);
  }
}

const mapStateToProps = (state, ownProps) => {
  console.log(ownProps)
  return { stream: state.streams };
}

export default connect(mapStateToProps, { fetchStream })(StreamEdit);

原因

React Router v6 完全移除了自动向组件注入match、location、history这些路由props的机制,不管你用Component还是element属性渲染组件,都不会拿到这些旧版的路由props。

解决办法

1. 给类组件套一个自定义的withRouter高阶组件

v6官方不再提供withRouter,但可以自己封装一个:

// 新建withRouter.js
import { useParams, useLocation, useNavigate } from 'react-router-dom';

export default function withRouter(Component) {
  return function WrappedComponent(props) {
    const params = useParams();
    const location = useLocation();
    const navigate = useNavigate();
    return <Component {...props} params={params} location={location} navigate={navigate} />;
  };
}

然后修改StreamEdit的导出:

import withRouter from './withRouter'; // 导入你封装的文件

// ...其他代码不变

export default withRouter(connect(mapStateToProps, { fetchStream })(StreamEdit));

之后在组件里用this.props.params.id替代原来的this.props.match.params.id:

componentDidMount() {
  this.props.fetchStream(this.props.params.id);
}

2. 把类组件改成函数组件(推荐)

v6更适配函数组件,用useParams钩子直接拿参数:

import React, { useEffect } from "react";
import { connect } from "react-redux";
import { fetchStream } from '../../actions';
import { useParams } from 'react-router-dom';

const StreamEdit = (props) => {
  const { id } = useParams();

  useEffect(() => {
    props.fetchStream(id);
  }, [id, props.fetchStream]);

  // 这里写原来的组件逻辑,比如渲染内容
  return <div>编辑流: {id}</div>;
};

const mapStateToProps = (state) => {
  return { stream: state.streams };
};

export default connect(mapStateToProps, { fetchStream })(StreamEdit);

3. 直接在Route的element里传递参数(不推荐)

如果非要保留类组件,也可以在App.js的Route里用element属性手动传,但本质还是要结合钩子:

// App.js里修改Route
<Route path='/streams/edit/:id' element={<StreamEdit />} />

但这种方式还是得用上面的withRouter或者把组件改成函数组件才能拿到id,所以不如直接用前两种方法。


内容的提问来源于stack exchange,提问作者saba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 13:22:07