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

使用Material UI Grid组件时出现Invalid hook call及useContext报错

问题场景

React项目中编写JoinChat组件时,引入Material UI的Grid组件包裹页面内容,页面渲染失败。组件完整代码如下:

import React, { useEffect } from "react";
import { useStore } from "../zustand/store";
import shallow from "zustand/shallow";
import Grid from "@mui/material/Grid";

export const JoinChat = () => {
    const [userCount, setUserCount] = useStore(
        (state) => [state.userCount, state.setUserCount],
        shallow
    );
    const setChat = useStore((state) => state.setChat);
    const socket = useStore((state) => state.socket);

    useEffect(() => {
        socket.on("user_count", (data) => {
            console.log("user count run in join chat");
            setUserCount(data);
        });
    }, [socket, setUserCount]);

    const joinChat = async () => {
        if ("geolocation" in navigator) {
            await navigator.geolocation.getCurrentPosition(async (pos) => {
                const location = {
                    x: pos.coords.longitude,
                    y: pos.coords.latitude,
                };
                await socket.emit("create_chat", location);
                setChat(true);
            });
        } else {
            alert("You location is not available");
        }
    };

    return (
        <Grid>
            <div>
                {userCount ? <p>People online {userCount}</p> : null}
                <button onClick={joinChat}>Join chat</button>
            </div>
        </Grid>
    );
};

控制台抛出两类报错:

  • 警告:Invalid hook call
  • 类型错误:cannot read properties of null (reading 'useContext')
    控制台报错截图
    移除所有Material UI组件后,页面可正常渲染,无任何警告或错误。
根因分析

该问题由项目依赖树中存在多份React实例,或React与MUI版本不兼容导致:

  • MUI组件内部会调用useContext等React内置Hook,按照React的Hook规则,Hook必须在对应React实例的组件渲染上下文中调用。如果MUI依赖引用的React,和业务代码运行时加载的React不是同一个实例,MUI内部调用Hook时就找不到对应的上下文,直接抛出上述两类错误。
  • 移除MUI组件后报错消失,是因为业务代码自身调用Hook时使用的是当前项目加载的React实例,不存在跨实例调用Hook的问题。

常见触发场景:

  • MUI版本与项目React版本不兼容,例如使用MUI v5时React版本低于17.0.0
  • 依赖安装异常,导致MUI所在的依赖层级下单独安装了一份独立的React副本
  • 本地调试(npm link/monorepo场景)时,主项目和依赖包各自加载了不同路径下的React
修复步骤

按优先级依次操作即可解决:

  1. 对齐版本要求
    MUI v5要求React版本不低于17.0.0,先升级React到兼容版本:
    npm install react@^18.2.0 react-dom@^18.2.0
    
  2. 清理依赖缓存重新安装
    这是解决多实例问题最常用的手段,删除现有依赖目录和锁文件后重新安装,保证依赖树中仅存在一份React实例:
    # npm 执行以下命令
    rm -rf node_modules package-lock.json
    npm install
    
    # yarn 执行以下命令
    rm -rf node_modules yarn.lock
    yarn install
    
    # pnpm 执行以下命令
    rm -rf node_modules pnpm-lock.yaml
    pnpm install
    
  3. 构建工具强制指定React解析路径
    如果重新安装依赖后问题仍存在,可以在构建配置中添加别名,强制所有模块引用React时都指向项目根目录下的React实例:
    Webpack配置示例:
    // webpack.config.js
    const path = require('path')
    module.exports = {
      // 其余配置省略
      resolve: {
        alias: {
          react: path.resolve(__dirname, 'node_modules/react'),
          'react-dom': path.resolve(__dirname, 'node_modules/react-dom')
        }
      }
    }
    
    Vite配置示例:
    // vite.config.js
    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    import path from 'path'
    
    export default defineConfig({
      plugins: [react()],
      resolve: {
        alias: {
          react: path.resolve(__dirname, './node_modules/react'),
          'react-dom': path.resolve(__dirname, './node_modules/react-dom')
        }
      }
    })
    
  4. 校验重复依赖
    执行包管理命令检查依赖树中是否存在多份React副本,确认修复结果:
    # npm
    npm ls react
    # yarn
    yarn list react
    
    输出结果中仅存在根目录下的一份React版本时,即修复完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:31:14