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

使用esm.sh引入react-three-fiber时触发Invalid Hook call错误的解决求助

问题描述

我尝试通过esm.sh运行react-three-fiber的Canvas组件,编写了如下HTML代码:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <script type="importmap">
        {
          "imports": {
            "@jsxImportSource": "https://esm.sh/react@18.2.0?dev",
            "react-dom/client": "https://esm.sh/react-dom@18.2.0/client?dev",
            "@react-three/fiber": "https://esm.sh/@react-three/fiber?dev"
          }
        }
    </script>
    <script type="module" src="https://esm.sh/run"></script>
    <title>Document</title>
</head>
<body>
    <div id="root"></div>

<script type="text/babel" >
    import {createRoot} from 'react-dom/client';
    import {Canvas} from '@react-three/fiber';

    function App() {
        return (
            <div>
                <Canvas >
                </Canvas>
            </div>
        );
    }

    createRoot(window.root).render(<App />);
</script>
</body>
</html>

运行时出现以下错误:

its-fine.development.mjs:68 警告:无效的Hook调用。Hook只能在函数组件的主体内部调用。可能的原因如下:
1. React与渲染器(如React DOM)版本不匹配
2. 违反了Hook的使用规则
3. 应用中存在多个React副本
查看React官方文档的无效Hook调用相关内容获取调试和修复建议。

react.development.js:1650 Uncaught TypeError: Cannot read properties of null (reading 'useMemo')
    at Module.useMemo2 (react.development.js:1650:21)
    at Canvas (react-three-fiber.esm.js:125:9)
    at renderWithHooks (react-dom.development.js:16305:18)
    at updateForwardRef (react-dom.development.js:19226:20)
    at beginWork (react-dom.development.js:21636:16)
    at HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
    at invokeGuardedCallback (react-dom.development.js:4277:31)
    at beginWork$1 (react-dom.development.js:27451:7)
    at performUnitOfWork (react-dom.development.js:26560:12)

its-fine.development.mjs:68 上述错误发生在<ForwardRef(Canvas)>组件中:
    at Canvas (https://esm.sh/v135/@react-three/fiber@8.16.6/es2022/fiber.development.mjs:2015:3)
    at FiberProvider (https://esm.sh/v135/its-fine@1.2.5/es2022/its-fine.development.mjs:71:21)
    at CanvasWrapper
    at div
    at App
建议在组件树中添加错误边界来自定义错误处理行为。
访问React官方文档的错误边界相关内容了解更多信息。

通过浏览器Sources面板发现,页面同时加载了React v18.2.0和v18.3.1两个版本,推测这是导致无效Hook调用错误的原因,请问该如何解决?

(原问题附带CodeSandBox示例)

解决方案

核心是强制所有依赖统一使用同一个React版本,避免多副本冲突,具体调整如下:

  • 完善Import Map,锁定React版本
    原import map只定义了部分包,需要添加react和react-dom的直接映射,同时强制@react-three/fiber依赖指定版本的React,修改后的import map如下:

    <script type="importmap">
        {
          "imports": {
            "react": "https://esm.sh/react@18.2.0?dev",
            "react-dom": "https://esm.sh/react-dom@18.2.0?dev",
            "react-dom/client": "https://esm.sh/react-dom@18.2.0/client?dev",
            "@react-three/fiber": "https://esm.sh/@react-three/fiber@8.16.6?dev&deps=react@18.2.0,react-dom@18.2.0"
          }
        }
    </script>
    

    这样可以避免依赖自动拉取最新版React,确保所有模块共用同一个18.2.0版本。

  • 修正ReactDOM挂载目标
    原代码中createRoot(window.root)的写法错误,应该通过DOM API获取挂载节点:

    createRoot(document.getElementById('root')).render(<App />);
    
  • 调整JSX导入源
    原import map中的@jsxImportSource写法不正确,可在模块脚本顶部添加注释指定JSX编译源:

    /** @jsxImportSource react */
    import {createRoot} from 'react-dom/client';
    import {Canvas} from '@react-three/fiber';
    
  • 验证版本一致性
    修改后刷新页面,在浏览器Sources面板中检查React版本,确认只有18.2.0一个版本被加载,此时Hook调用错误即可解决。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 19:19:58