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

React无法识别Context组件为函数组件,触发Invalid Hook Call错误

问题排查与解决

问题背景

开发用于切换抽屉状态的Context组件时,调用useReducer触发了无效Hook调用错误,此前开发过类似组件未遇此问题。

代码

import React from 'react';
import { useReducer } from 'react';

export const DrawerContext = React.createContext();

export function toggleDrawerDisplayAction(dispatch, currentDrawerState) {
    if (currentDrawerState == "none") {
        dispatch({ type: "SHOW_DRAWER", payload: "block" });
    } else {
        dispatch({ type: "HIDE_DRAWER", payload: "none" });
    }
}

export function HideDrawerAction(dispatch) {
    dispatch({ type: "HIDE_DRAWER", payload: "none" });
}

export function drawerReducer(state, action) {
    console.log(action);
    switch (action.type) {
        case "SHOW_DRAWER":
            return { currentDrawerState: action.payload };
        case "HIDE_DRAWER":
            return { currentDrawerState: action.payload };
        default:
            return { currentDrawerState: state };
    }
}

let DrawerContextProvider = function (props) {
    const [state, dispatch] = useReducer(drawerReducer, {
        currentDrawerState: "none"
    })

    return (<DrawerContext.Provider value={{ ...state, dispatch }}>
        {props.children}
    </DrawerContext.Provider>)
}

export default DrawerContextProvider;

错误信息

react-dom.development.js:16227 Uncaught Error: 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
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
    at Object.throwInvalidHookError (react-dom.development.js:16227:1)
    at useReducer (react.development.js:1626:1)

排查与解决思路

1. 检查React与React DOM版本一致性

查看项目package.json中react和react-dom的版本号,确保两者完全一致。若版本不匹配,执行对应命令更新:

# npm
npm install react@latest react-dom@latest

# yarn
yarn add react@latest react-dom@latest

2. 确认组件使用方式符合规范

确保DrawerContextProvider是作为React组件被渲染,而非普通函数调用:

  • 错误用法:直接调用函数 DrawerContextProvider()
  • 正确用法:以组件形式渲染
    <DrawerContextProvider>
      {/* 子组件内容 */}
    </DrawerContextProvider>
    

你的组件代码中useReducer位于函数组件顶层,本身符合Hook规则,但误用组件会触发该错误。

3. 检查是否存在多个React副本

项目中若存在多个React包(比如子依赖引入了独立的React),会导致Hook调用失败。执行以下命令查看依赖树:

# npm
npm ls react

# yarn
yarn list react

若发现多个版本,可通过配置强制统一版本:

  • npm:在package.json中添加
    "overrides": {
      "react": "$react",
      "react-dom": "$react-dom"
    }
    
  • yarn:在package.json中添加
    "resolutions": {
      "react": "^x.x.x",
      "react-dom": "^x.x.x"
    }
    

替换^x.x.x为你需要的版本号,之后重新安装依赖。

额外代码优化建议

你的drawerReducer默认分支存在逻辑问题:

// 错误:将state对象赋值给currentDrawerState,导致状态结构嵌套
default:
    return { currentDrawerState: state };

应改为直接返回原state:

default:
    return state;

否则后续状态会变成{currentDrawerState: {currentDrawerState: "none"}},导致状态读取错误。

内容的提问来源于stack exchange,提问作者M.KH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:55:23