Next.js使用react-3d-viewer加载数据库glTF文件报window未定义如何解决
问题原因
window is not defined报错由Next.js的服务端渲染(SSR)特性触发:react-3d-viewer库底层依赖浏览器全局对象window,而Next.js默认会在服务端执行组件代码,服务端环境不存在window对象,因此抛出错误。
解决方案
方案1:修改导入方式适配现有代码
不需要调整业务逻辑和配置文件,只需将react-3d-viewer的组件改为Next.js动态导入形式,关闭服务端渲染即可:
- 首先导入Next.js的动态导入工具:
import dynamic from 'next/dynamic'
- 删除原有的
react-3d-viewer静态导入语句,替换为以下动态导入代码:
// 动态导入组件并关闭服务端渲染 const GLTFModel = dynamic(() => import('react-3d-viewer').then(mod => mod.GLTFModel), { ssr: false }) const AmbientLight = dynamic(() => import('react-3d-viewer').then(mod => mod.AmbientLight), { ssr: false }) const DirectionLight = dynamic(() => import('react-3d-viewer').then(mod => mod.DirectionLight), { ssr: false })
可选优化:由于filePath是在componentDidMount阶段异步从数据库获取的,初始值为空,可以在渲染GLTF组件前增加判断,避免触发无效资源请求:
{this.state.filePath && ( <GLTFModel src={this.state.apiUrl + '/api/v1/visitImageRequirementInfo/getImageByImagePathId?imagePath=' + this.state.filePath}> <AmbientLight color={0xffffff}/> <DirectionLight color={0xffffff} position={{x:100,y:200,z:100}}/> <DirectionLight color={0xff00ff} position={{x:-100,y:200,z:-100}}/> </GLTFModel> )}
方案2:更换兼容性更好的渲染库
如果react-3d-viewer后续仍有其他兼容性问题,可改用@react-three/fiber。该库是Three.js的React封装,对Next.js适配性更强,支持加载任意合法URL来源的glTF文件,包括你从数据库获取的远程地址,性能和可定制性更高,使用时同样通过动态导入关闭SSR即可正常运行。
内容的提问来源于stack exchange,提问作者jack
相关产品推荐
相关产品推荐

