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
相关产品推荐
相关产品推荐

