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

解决JS应用引入框架组件时的Invalid hook call错误

React组件引入时的"Invalid hook call"错误排查及多选下拉框取值方案

问题详情

在JS应用中引入并使用框架组件时,页面函数内引入组件后出现大量Invalid hook call错误。已按照建议检查项目是否存在重复React实例:

执行npm ls react-dom的结果:

└─┬ react-select@5.7.0
  ├── react-dom@18.2.0
  └─┬ react-transition-group@4.4.5
    └── react-dom@18.2.0 deduped

执行npm ls react的结果:

├─┬ @fortawesome/react-fontawesome@0.2.0
│ └── react@18.2.0
├─┬ multiselect-react-dropdown@2.0.25
│ └── react@18.2.0 deduped
└─┬ react-select@5.7.0
  ├─┬ @emotion/react@11.10.5
  │ ├─┬ @emotion/use-insertion-effect-with-fallbacks@1.0.0
  │ │ └── react@18.2.0 deduped
  │ └── react@18.2.0 deduped
  ├─┬ react-dom@18.2.0
  │ └── react@18.2.0 deduped
  ├─┬ react-transition-group@4.4.5
  │ └── react@18.2.0 deduped
  ├── react@18.2.0 deduped
  └─┬ use-isomorphic-layout-effect@1.1.2
    └── react@18.2.0 deduped

从结果看不存在重复React的问题。以下是实现下拉选择框的代码(同时需要获取通过setPractices从多选下拉框取数的方法):

import React from 'react'
import { useState } from 'react'
import Select from 'react-select'

const FormPage = () => {
    const [ practices, setPractices ] = useState([])

    const NZoptions = [
        { value: 'restructuring', label: 'Restructuring and Insolvency' },
        { value: 'mergers', label: 'Mergers and Acquisitions' },
        { value: 'banking', label: 'Banking and Finance' }
    ]

    return (
        <section className="form-section">
                <div className="form-input multi">
                    <label>Practices:</label>
                        <Select
                            defaultValue={[ NZoptions[0], NZoptions[1] ]}
                            isMulti
                            name="practices"
                            options={ NZoptions }
                            className="basic-multi-select"
                            classNamePrefix="select"
                        />
                </div>
        </section>
    )
}

运行代码后,浏览器控制台仍提示错误:

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app

补充说明:

  • 代码基于React Select官方文档实现
  • 引入任何第三方框架组件都会触发该错误
  • 移除模块中的useState后错误依然存在

排查方向与解决方案

一、错误排查(针对Invalid hook call)

  1. 强制统一React与React DOM版本
    手动确认package.json中react和react-dom版本完全一致,若有差异,执行以下命令强制同步:

    npm install react@18.2.0 react-dom@18.2.0
    
  2. 检查组件调用方式
    确保FormPage是作为React组件渲染(如<FormPage />),而非以普通函数方式调用(如FormPage())——这是违反Hook规则的常见场景。

  3. 修复项目依赖链接问题
    若项目存在本地包或monorepo结构,可能导致React实例重复,在项目根目录执行以下命令强制统一依赖:

    npm link ./node_modules/react
    npm link ./node_modules/react-dom
    
  4. 排查构建工具配置
    检查Webpack或Vite等构建工具的配置文件,确认没有重复引入React的配置,或externals设置未导致React被多次加载。

二、多选下拉框取值实现(setPractices)

为Select组件添加onChange回调,将选中选项同步到practices状态中:

// 修改后的Select组件代码
<Select
    defaultValue={[ NZoptions[0], NZoptions[1] ]}
    isMulti
    name="practices"
    options={ NZoptions }
    className="basic-multi-select"
    classNamePrefix="select"
    // 新增onChange回调
    onChange={(selectedOptions) => {
        // 若只需要存储选项的value值
        const selectedValues = selectedOptions.map(opt => opt.value)
        setPractices(selectedValues)
        // 若需要存储完整的选项对象,直接传入即可
        // setPractices(selectedOptions)
    }}
/>

同时可在初始化状态时同步默认值:

// 存储value值的初始化
const [ practices, setPractices ] = useState([ NZoptions[0].value, NZoptions[1].value ])
// 或存储完整选项对象的初始化
// const [ practices, setPractices ] = useState([ NZoptions[0], NZoptions[1] ])

内容的提问来源于stack exchange,提问作者Joe Byrne

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:10:25