R3F报错:Div不属于THREE命名空间,extend使用遇未定义问题求助
问题:R3F 报错 "Div is not part of the THREE namespace!"
报错信息
Uncaught Error: R3F: Div is not part of the THREE namespace! Did you forget to extend
页面提示:R3F: Div is not part of the THREE namespace! Did you forget to extend?
代码示例
import React, { Suspense, useEffect, useState } from "react"; import { Canvas } from "@react-three/fiber"; import { OrbitControls, Preload, useGLTF } from "@react-three/drei"; import CanvasLoader from '../Loader'; const Computers = () => { const computer = useGLTF("./desktop_pc/scene.gltf"); return ( <mesh> <hemisphereLight intensity={0.15} groundColor="black" /> <pointLight intensity={1}/> <primitive object={computer.scene} /> </mesh> ) } const ComputersCanvas=()=>{ return ( <Canvas frameloop='demand' shadows camera={{ position: [20, 3, 5], fov: 25 }} gl={{ preserveDrawingBuffer: true }} > <Suspense fallback={<CanvasLoader />}> <OrbitControls enableZoom={false} maxPolarAngle={Math.PI / 2} minPolarAngle={Math.PI / 2} /> <Computers /> </Suspense> <Preload all /> </Canvas> ); }; export default ComputersCanvas;
额外问题说明
- 未在 Canvas 内使用任何 Div 元素
- 尝试使用
extend({OrbitControls, Preload, useGLTF})时,出现 "extended is not defined" 错误
解决方案
1. 排查 CanvasLoader 组件
报错指向的 Div 大概率来自你引入的 CanvasLoader 组件。R3F 的 Canvas 内部只能渲染 Three.js 相关的 React 组件(如 mesh、light、primitive 等),不能直接渲染 HTML 元素(比如 div)。
- 检查
../Loader路径下的 CanvasLoader 组件,确认它是否返回了 HTML 元素(如 div、span)。如果是,需要把这个 Loader 放在 Canvas 组件外面,或者改用 R3F 兼容的 3D 加载器组件。
2. 修正 extend 的使用方式
你用错了 extend 的语法,且 OrbitControls、Preload 这类 drei 组件不需要手动调用 extend——drei 已经自动处理了 Three.js 对象的扩展逻辑。
若需要手动扩展 Three.js 原生类(比如直接从 three 包导入的控件),正确用法如下:
import { extend } from '@react-three/fiber'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; extend({ OrbitControls });
但你当前从 drei 导入组件的场景下,完全不需要这一步,直接使用即可。
3. 调整 Suspense 的位置
将 Suspense 移到 Canvas 组件外部,避免在 Canvas 内部渲染 Suspense fallback 中的 HTML 元素:
const ComputersCanvas=()=>{ return ( <Suspense fallback={<CanvasLoader />}> <Canvas frameloop='demand' shadows camera={{ position: [20, 3, 5], fov: 25 }} gl={{ preserveDrawingBuffer: true }} > <OrbitControls enableZoom={false} maxPolarAngle={Math.PI / 2} minPolarAngle={Math.PI / 2} /> <Computers /> <Preload all /> </Canvas> </Suspense> ); };
内容的提问来源于stack exchange,提问作者Dhiraj Gilda
相关产品推荐
相关产品推荐

