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

React类组件中this.props.match.params.id报错:无法读取params属性

解决React Router v6中类组件无法获取路由参数的问题

问题描述

跟随旧版React教程开发,所有组件均为类组件。在EditExercise组件的componentDidMount方法中尝试通过this.props.match.params.id获取URL中的id参数时,触发报错:

Uncaught TypeError: Cannot read properties of undefined (reading 'params')

相关代码如下:

EditExercise.js

class EditExercise extends Component{
  
    constructor(props){
        super(props )
        
        this.state={
            username:"",
            description:"",
            duration:0,
            date:new Date(),
            users:[]
        }
    }
    
    componentDidMount(){
      
        axios.get('http://localhost:5000/exercises/'+ this.props.match.params.id)
        .then(response=>{
            this.setState({
                username:response.data.username,
                description:response.data.description,
                duration:response.data.duration,
                date: new Date(response.data.date)
            })
        }).catch(function(error){
            console.log(error)
        })
    }
    // ... 其他组件代码
}

路由配置(App.js)

function App() {
  return (
    <Router>
      <Navbar/>
       <Routes>
       <Route index element={<ExercisesList/>}/>
        <Route path="edit/:id" element={<EditExercise/>}/>
       </Routes> 
    </Router>
  );
}

曾尝试使用withRouter但需降级react-router-dom,希望保留当前版本解决问题。

解决方案

React Router v6不再自动为组件注入match、location等路由相关props,同时移除了官方withRouter高阶组件。针对类组件,提供两种无需降级的解决办法:

方案1:自定义withRouter高阶组件

自己封装一个withRouter,利用React Router v6的hooks获取路由信息,再传递给类组件:

import { useParams, useLocation, useNavigate } from 'react-router-dom';

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

修改EditExercise的导出语句:

export default withRouter(EditExercise);

之后在componentDidMount中通过this.props.params.id获取id:

componentDidMount(){
    axios.get('http://localhost:5000/exercises/'+ this.props.params.id)
    // ... 后续逻辑保持不变
}

方案2:用函数组件作为中间层

创建一个函数组件,通过useParams获取路由参数,再将其作为props传递给类组件:

// 新建EditExerciseWrapper.jsx
import { useParams } from 'react-router-dom';
import EditExercise from './EditExercise';

const EditExerciseWrapper = () => {
  const { id } = useParams();
  return <EditExercise exerciseId={id} />;
};

更新路由配置:

<Route path="edit/:id" element={<EditExerciseWrapper/>}/>

最后在EditExercise中使用this.props.exerciseId:

componentDidMount(){
    axios.get('http://localhost:5000/exercises/'+ this.props.exerciseId)
    // ... 后续逻辑保持不变
}

方案1适合需要在多个类组件中复用路由逻辑的场景,方案2更适合单个组件的简单需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 22:40:41