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

React类组件在新版react-router-dom中获取URL路由参数的实现方法

解决方案

React Router v6 不再为类组件默认注入match、location等路由属性,也不支持在类组件内部直接调用useParams等Hook,你可以通过自定义高阶组件(HOC)封装Hook能力,透传给类组件使用,具体操作如下:


步骤1:自定义withRouter高阶组件

v6版本移除了原本内置的withRouter,你可以自行实现一个,用来把路由相关能力封装后透传给类组件:

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

function withRouter(Component) {
  function ComponentWithRouterProp(props) {
    const params = useParams();
    const location = useLocation();
    const navigate = useNavigate;
    // 所有路由相关属性都会注入到props的router字段中
    return <Component {...props} router={{ params, location, navigate }} />;
  }
  return ComponentWithRouterProp;
}

你可以把这段代码抽成公共工具文件,也可以直接写在Post组件文件内。


步骤2:修改Post组件代码

需要调整的点如下:

  • 移除类组件内的useParams导入(类组件不能直接调用Hook)
  • 导出时用自定义的withRouter包裹组件,获取路由参数能力
  • 初始化state的mydata为对象而非数组,匹配单条博客数据的结构
  • 在componentDidMount中通过this.props.router.params.id拿到URL中的id,拼接在请求URL末尾
  • 增加加载状态判断,避免初始渲染无数据时报错

修改后的完整Post组件代码:

import axios from 'axios'
import React, { Component, Fragment } from 'react'

// 上面的withRouter代码如果抽成公共文件,这里直接导入即可
function withRouter(Component) {
  function ComponentWithRouterProp(props) {
    const params = useParams();
    const location = useLocation();
    const navigate = useNavigate;
    return <Component {...props} router={{ params, location, navigate }} />;
  }
  return ComponentWithRouterProp;
}

class Post extends Component {
    constructor(props) {
        super(props)
        this.state = {
            // 单条数据是对象,初始化为空对象
            mydata: {},
            loading: true
        }
    }

    componentDidMount() {
        // 从props中获取URL参数里的id
        const postId = this.props.router.params.id
        axios.get(`https://jsonplaceholder.typicode.com/posts/${postId}`)
        .then((response)=>{
            if(response.status===200)
            {
                this.setState({
                    mydata:response.data,
                    loading: false
                })
            }
        })
        .catch((error)=>{
            this.setState({loading: false})
        })
    }
    
    render() {
        const {mydata, loading} = this.state;
        if(loading) return <Fragment>数据加载中</Fragment>

        return (
            <Fragment>
                <h1>{mydata.title}</h1>
                <p>{mydata.body}</p>
            </Fragment>
        )
    }
}

// 用withRouter包裹后导出
export default withRouter(Post)

步骤3:路由配置无需修改

你原本的路由配置可以直接沿用,不需要做任何调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:15:03