如何将React JS组件迁移至React TS项目并解决useId报错问题
React JS 3D组件迁移至React TS的解决方案及报错修复
报错原因分析
你遇到的useId is not a function错误,是因为当前项目的React版本低于18,而@react-three/fiber或@react-three/drei的新版本依赖React 18新增的useId Hook,导致运行时找不到该方法。
修复方案与迁移步骤
1. 升级React依赖(推荐方案)
将React和ReactDOM升级到18版本,匹配三方库的依赖要求:
# npm npm install react@^18 react-dom@^18 # yarn yarn add react@^18 react-dom@^18
同时更新项目的根渲染逻辑为React 18的createRoot模式:
// main.tsx import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render(<App />);
2. 降级三方库(兼容旧React版本)
如果无法升级React,可以降级@react-three/fiber和@react-three/drei到支持React 17的版本:
# npm npm install @react-three/fiber@^7 @react-three/drei@^9 # yarn yarn add @react-three/fiber@^7 @react-three/drei@^9
3. 组件迁移到TypeScript
将原JS组件改为.tsx文件,并添加类型定义:
import React from 'react'; import { Canvas } from '@react-three/fiber'; import { useGLTF, Stage, PresentationControls } from '@react-three/drei'; import type { Object3D } from 'three'; // 声明GLB文件的导入类型 declare module '*.glb' { const url: string; export default url; } // 定义Model组件的Props类型 interface ModelProps { scale?: number; // 允许传递primitive支持的其他属性 [key: string]: any; } function Model({ scale = 1, ...props }: ModelProps) { const { scene } = useGLTF('/res/bmw.glb'); // 类型断言确保scene符合Object3D类型 return <primitive object={scene as Object3D} scale={scale} {...props} />; } export function Object3D() { return ( <Canvas dpr={[1, 2]} shadows camera={{ fov: 45 }} style={{ position: 'absolute' }}> {/* 修正原代码中颜色值的多余字符:#1010101 -> #101010 */} <color attach="background" args={['#101010']} /> <PresentationControls speed={1.5} global zoom={0.5} polar={[-0.1, Math.PI / 4]}> <Stage environment={null}> <Model scale={0.01} /> </Stage> </PresentationControls> </Canvas> ); }
额外注意事项
- 确保GLB文件的路径正确,
/res/bmw.glb需要对应项目public目录下的res文件夹,或者调整为相对导入(如果用webpack等打包工具处理静态资源) - 如果使用TypeScript,需要安装three的类型依赖:
npm install @types/three --save-dev
内容的提问来源于stack exchange,提问作者Alex Lee
相关产品推荐
相关产品推荐

