React Router v6类组件获取URL参数报props.match is undefined
问题原因
你用的是 React Router v6 版本,这个版本彻底移除了旧版v5中自动给路由渲染的类组件注入match/location/history props的逻辑,所以不管是写props.match还是this.props.match,拿到的都会是undefined,和你组件内部写法无关,是版本API变更导致的。
另外你贴的Data组件代码本身也有结构问题:把请求函数、接口调用逻辑全堆在了constructor构造函数里,不符合React类组件的写法规范,很容易引出额外的执行时机问题。
解决方案
两种方案选一个就行:
方案1:保留类组件写法,用高阶组件封装路由参数
类组件不能直接使用useParams这类Hook,你可以自己写一个极简的高阶组件,把Hook拿到的路由参数作为普通props传给类组件:
- 先写一个通用的参数注入高阶组件:
import { useParams } from 'react-router-dom'; export const withParams = (WrappedComponent) => { return (props) => { const params = useParams(); return <WrappedComponent {...props} params={params} />; }; };
- 修改Data组件的代码,调整错误的结构,用高阶组件包裹后导出:
import React, { Component } from 'react'; import { withParams } from './你的高阶组件存放路径'; // 接口请求逻辑抽到组件外部,避免重复声明 const fetchUsers = async (user) => { const res = await fetch(`https://api.github.com/search/users?q=${user}`); const data = await res.json(); return { data }; }; class Data extends Component { constructor(props) { super(props); this.state = { user: [] }; } // 数据请求放到componentDidMount生命周期,不要写在constructor里 componentDidMount() { const { id } = this.props.params; console.log('username', id); fetchUsers(id).then((res) => { this.setState({ user: res.data.items }); }); } render() { // 你自己的页面渲染逻辑 return <div>{/* 渲染user列表 */}</div>; } } // 包裹后导出,原有路由配置不用改 export default withParams(Data);
改完之后你在组件内直接通过this.props.params.id就能拿到路由参数,不会再报undefined错误。
方案2:改写为函数组件(官方推荐写法)
如果没有必须保留类组件的强需求,直接改写成函数组件用官方Hook是最省事的写法,不需要额外封装高阶组件:
import React, { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; const fetchUsers = async (user) => { const res = await fetch(`https://api.github.com/search/users?q=${user}`); const data = await res.json(); return { data }; }; const Data = () => { const [user, setUser] = useState([]); const { id } = useParams(); useEffect(() => { console.log('username', id); fetchUsers(id).then((res) => { setUser(res.data.items); }); }, [id]); // 页面渲染逻辑 return <div>{/* 渲染user列表 */}</div>; }; export default Data;
注意避坑
- React Router v6 不再支持旧版类组件的props注入写法,所有路由能力都优先通过Hook暴露,类组件使用必须自行通过高阶组件做适配,不要照搬v5的老教程写法。
- 构造函数constructor只适合做state初始化、事件方法this绑定这类初始化操作,数据请求、订阅这类副作用逻辑不要写在constructor里,类组件统一放到
componentDidMount生命周期执行,避免出现执行时机异常、内存泄漏问题。
内容的提问来源于stack exchange,提问作者genebent
相关产品推荐
相关产品推荐

