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

React类组件使用useParams获URL参数报Invalid hook call错误如何解决

问题原因

useParams 是 React Router 提供的Hook API,仅支持在函数组件的顶层作用域中调用,你的代码在类组件的handleReservation方法内调用Hook,不符合Hook的使用规则,因此触发Hooks can only be called inside of the body of a function component报错。

解决方案

方案1:通过高阶组件封装给类组件传递路由参数

如果你需要保留类组件写法,可以自定义高阶组件包裹你的类组件,将路由参数通过props注入:

import { useParams } from 'react-router-dom';

// 自定义高阶组件,将params注入到被包裹组件的props中
function withParams(Component) {
  return props => <Component {...props} params={useParams()} />;
}

之后修改你的SimpleMap组件逻辑:

  1. 删掉handleReservation方法内的let params = useParams();这行代码
  2. 取参数改为this.props.params.serviceID
  3. 导出组件时用高阶组件包裹:
export default withParams(SimpleMap);

方案2:将类组件改写为函数组件(更推荐)

目前React官方更推荐使用函数组件配合Hook开发,改写后的代码示例如下:

import { useParams } from 'react-router-dom';
import { useState } from 'react';
import axios from 'axios';
import Cookies from 'js-cookie';
// 其余依赖导入保持和原代码一致

const AnyReactComponent = ({ text }) => <div>{<LocationOnIcon color="primary"/>}</div>;

const SimpleMap = (props) => {
  const [resdate, setResdate] = useState(new Date().toISOString().substr(0,10));
  const params = useParams(); // 直接在函数组件顶层调用useParams

  const handleReservation = async () => {
    await axios({
      method: 'post',
      url: 'http://localhost:3001/reservation',
      headers: {},
      data: {
        serviceID: params.serviceID,
        userID: Cookies.get('userID'),
        reservationDate: resdate
      }
    })
  };

  return (
    <div style={{ height: '50vh', width: '35%', justifyContent: 'flex-end' }}>
      <GoogleMapReact
        bootstrapURLKeys={{ key: 'apiKey' }}
        defaultCenter={ AnyReactComponent ? props.greatPlaceCoords: props.center}
        defaultZoom={props.zoom}
        lat={45.756659}
        lng={21.228703}
      >
        <AnyReactComponent
          {...props.greatPlaceCoords}
          text={<><LocationOnIcon/> location</>}
        />
      </GoogleMapReact>
      <Button onClick={handleReservation}>
        Make a reservation
      </Button>
      <Booking/>
    </div>
  );
}

SimpleMap.defaultProps = {
  center: {
    lat: 59.95,
    lng: 30.33
  },
  greatPlaceCoords: {
    lat:45.756659,
    lng:21.228703
  },
  zoom: 11,
};

export default SimpleMap;
其他代码问题修正

你的原代码还存在2处语法错误:

  • Button组件标签未闭合,缺少结束的>和内容包裹标记
  • AnyReactComponent的text属性赋值写法错误,不能把JSX写在字符串引号内

内容的提问来源于stack exchange,提问作者John Shelby

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:48:01