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

React调用useState触发Invalid hook call报错

问题背景

React项目开发中遇到如下场景:

  • 使用useState存储API接口返回的响应数据
  • 接口请求成功后,提取所需字段,通过map方法遍历处理生成新数组arr
  • 数组处理完成后,调用useState返回的setData方法更新data状态
  • 代码运行时抛出错误:"Invalid hook call. Hooks can only be called inside of the body of a function component",翻译为:无效的Hook调用:Hook只能在函数组件的函数体内部调用

异常代码片段

import {useEffect, useState} from 'react'
import logo from './logo.svg';
import './App.css';
import axios from 'axios'
import ReactSearchBox from 'react-search-box'
// 问题点:冗余的错误导入
import { set } from 'express/lib/application';

function App() {
  let [data, setData] = useState()
  
  useEffect(onMount,[])

  function onMount(){
      axios.get('https://restcountries.com/v3.1/all').then(res=>{
        let arr = res.data.map((c)=>{
          return {key:c.name.common, value: c.name.common}
        })
        setData(arr)   
      })
  }
报错原因
  • 核心诱因是代码中存在编辑器自动补全时误加的冗余导入:import { set } from 'express/lib/application'。express是服务端Node.js框架,内部依赖大量Node环境专属API,无法在浏览器端运行,这行完全无用的导入会导致打包后的代码运行逻辑异常,干扰React运行时的Hook调用校验机制,最终抛出无效Hook调用的错误。
  • 存在隐藏渲染错误:useState()未传入初始值,data初始状态为undefined,组件首次渲染执行data.length > 0判断时,会尝试在undefined上读取length属性,触发类型错误。
  • 若删除错误导入后仍复现报错,大概率是项目存在React多实例、React与ReactDOM版本不匹配问题,这类问题也会触发相同的Hook报错。
修复方案
  1. 直接删除无效的express相关导入行,前端业务代码不需要引入任何express模块。
  2. 给useState传入空数组作为初始值,将状态声明修改为const [data, setData] = useState([]),规避首次渲染时的undefined属性访问错误。
  3. 若仍存在报错,检查项目依赖的React版本一致性:
    • npm项目执行命令:npm ls react
    • yarn项目执行命令:yarn list react
      确保依赖树中仅存在一个版本的react,且react与react-dom版本完全对应。若存在多版本冲突,删除node_modules目录和依赖锁文件后重新执行依赖安装即可。

修复后完整代码

import "./styles.css";
import axios from 'axios'
import ReactSearchBox from 'react-search-box'
import {useEffect, useState} from 'react'

export default function App() {
  const [data, setData] = useState([])
  
  useEffect(() => {
    axios.get('https://restcountries.com/v3.1/all').then(res=>{
      let arr = res.data.map((c)=>{
        return {key:c.name.common, value: c.name.common}
      })
      setData(arr)
    })
  }, [])

  return (
    <div className="App">
      <h1>Countries</h1>
      {data.length > 0 ? <ReactSearchBox
        placeholder="Placeholder"
        value="Doe"
        data={data}
        callback={(record) => console.log(record)}
      />: null}
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Amaan Imtiyaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:36:27