React类组件中this.props.match.params.id为undefined的解决方法
解决React类组件中this.props.match.params.id返回undefined的问题
问题原因
React Router v6 彻底移除了旧版本中通过组件props传递match、location等路由对象的机制,转而使用hooks API。但类组件无法直接调用hooks,因此原来的this.props.match会返回undefined。
解决方案
方案一:用函数组件做中间层传递参数
这是最直接的解决方式,不需要修改类组件的核心逻辑,仅在路由配置中添加一个函数组件作为中间层,通过useParams获取参数后传给类组件:
- 修改App.js的路由配置:
import { useParams } from 'react-router-dom'; // 包裹Event类组件的函数组件 const EventWrapper = () => { const params = useParams(); return <Event id={params.id} />; }; export default function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Layout />}> <Route path="admin/add-event" element={<AddEvent />} /> <Route path="admin/events" element={<AdminEvents />} /> <Route path="events" element={<Events />} /> {/* 替换原路由为包裹后的组件 */} <Route path="events/:id" element={<EventWrapper />} /> </Route> </Routes> </BrowserRouter> ); }
- 修改Event组件的
fetch方法,直接从props获取id:
fetch() { axios .get(`/api/events/${this.props.id}`) .then((response) => { this.setState({ // 修正原代码中的变量名错误:将user改为result result: response.data.result, loading: false, }); }) .catch((error) => { console.dir(error); this.setState({ error: error }); }); }
方案二:自定义withRouter高阶组件
如果有多个类组件需要路由相关数据,可以自定义一个withRouter高阶组件,将hooks的结果注入到类组件的props中:
- 实现withRouter:
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; };
- 给Event组件应用这个高阶组件:
// 替换原export语句 export default withRouter(Event);
- 在Event组件中通过
this.props.params.id获取参数:
fetch() { axios .get(`/api/events/${this.props.params.id}`) .then((response) => { this.setState({ result: response.data.result, loading: false, }); }) .catch((error) => { console.dir(error); this.setState({ error: error }); }); }
额外注意点
原Event组件中存在一处变量名错误:setState时赋值给了user,但render中使用的是this.state.result,这会导致渲染时event为null,进而引发event.title的报错,需要将user改为result。
内容的提问来源于stack exchange,提问作者Rue Vitale
相关产品推荐
相关产品推荐

