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

React类组件读取params报undefined 无法使用useParams求解决方案

错误原因

  1. 你当前使用的是react-router v6版本,该版本已经移除了类组件中原生支持的this.props.match属性,因此你调用this.props.match.params.id时会触发Cannot read properties of undefined (reading 'params')报错。
  2. useParams是react-router提供的Hook语法,仅支持在函数组件中调用,类组件内直接使用会报错。

可行解决方案

方案1:自定义withRouter高阶组件适配类组件(无需修改现有类组件核心逻辑)

react-router v6官方移除了原有的withRouter封装,你可以自行实现高阶组件注入路由参数:

  1. 在当前组件文件中添加自定义withRouter逻辑:
import { useParams, useNavigate, useLocation } from 'react-router-dom';

// 自定义高阶组件,为类组件注入路由相关属性
function withRouter(Component) {
  function ComponentWithRouterProp(props) {
    const location = useLocation();
    const navigate = useNavigate();
    const params = useParams();
    return <Component {...props} router={{ location, navigate, params }} />;
  }
  return ComponentWithRouterProp;
}
  1. 将原有获取id的逻辑替换:
    把所有的const id = this.props.match.params.id替换为const id = this.props.router.params.id
  2. 导出组件时用withRouter包裹:
export default withRouter(Feed2);

原有没用的import {useParams} from "react-router-dom"可以直接删除。

方案2:将类组件改写为函数组件(符合react-router v6的官方推荐写法)

改写后的完整代码如下,同时修复了你原代码中res.data.registration.color拼写错误的问题(少了s,应为res.data.registrations.color):

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Dropdown } from "react-bootstrap";
import { useParams } from "react-router-dom";

const Feed2 = () => {
  // 直接用useParams获取路由id
  const { id } = useParams();
  // 用useState管理表单状态
  const [formData, setFormData] = useState({
    vehicle: "",
    plateNo: "",
    owner: "",
    manufacturer: "",
    manufacturedYear: "",
    color: ""
  });

  const takInput = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const register = (e) => {
    e.preventDefault();
    const { plateNo, owner, manufacturer, manufacturedYear, color, vehicle } = formData;
    const data = { plateNo, owner, manufacturer, manufacturedYear, color, vehicle };

    console.log(data);
    axios.put(`http://localhost:8080/registrations/update/${id}`, data).then((res) => {
      if (res.data.success) {
        alert("Post Updated");
        setFormData({
          vehicle: "",
          plateNo: "",
          owner: "",
          manufacturer: "",
          manufacturedYear: "",
          color: ""
        });
      }
    });
  };

  // 用useEffect替代componentDidMount生命周期
  useEffect(() => {
    axios.get(`/registrations/${id}`).then((res) => {
      if (res.data.success) {
        setFormData({
          plateNo: res.data.registrations.plateNo,
          owner: res.data.registrations.owner,
          manufacturer: res.data.registrations.manufacturer,
          manufacturedYear: res.data.registrations.manufacturedYear,
          color: res.data.registrations.color,
          vehicle: res.data.registrations.vehicle
        });
      }
    });
  }, [id]);

  return (
    <div className="container">
      <div className="register-box">
        <div className="Top">
          <div className="box">
            <input placeholder="Enter the licence plate number "
              className="input2" name="plateNo" value={formData.plateNo} onChange={takInput} />
          </div>
        </div>
        <div className="box">
          <input placeholder="Enter the owners name "
            className="input2" name="owner" value={formData.owner} onChange={takInput} />
        </div>
        <div className="box">
          <input placeholder=" Manufactured Year "
            className="input2" name="manufacturedYear" value={formData.manufacturedYear} onChange={takInput} />
        </div>
        <div className="box">
          <input placeholder="Manufacturer"
            className="input2" name="manufacturer" value={formData.manufacturer} onChange={takInput} />
        </div>
        <div className="box">
          <input placeholder="Color of the vehicle "
            className="input2" name="color" value={formData.color} onChange={takInput} />
        </div>
        <div className="box">
          <input placeholder="Vehicle name "
            className="input2" name="vehicle" value={formData.vehicle} onChange={takInput} />
        </div>

        <Dropdown className="drop">
          <Dropdown.Toggle variant="success" id="dropdown-basic">
            Select Vehicle Type
          </Dropdown.Toggle>
          <Dropdown.Menu>
            <Dropdown.Item href="#/action-1">Car</Dropdown.Item>
            <Dropdown.Item href="#/action-2">Van</Dropdown.Item>
            <Dropdown.Item href="#/action-3">Bus</Dropdown.Item>
            <Dropdown.Item href="#/action-3">Lorry</Dropdown.Item>
            <Dropdown.Item href="#/action-3">Three-weeler</Dropdown.Item>
            <Dropdown.Item href="#/action-3">Bike</Dropdown.Item>
            <Dropdown.Item href="#/action-3">Other</Dropdown.Item>
          </Dropdown.Menu>
        </Dropdown>

        <div className="regbuttonContainer">
          <button className="Button" onClick={register}>Register Vehicle</button>
        </div>
      </div>
    </div>
  );
}

export default Feed2;

内容的提问来源于stack exchange,提问作者Code With Banchi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 15:36:03