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

在React中使用原生Three.js时出现renderer未定义错误求助

问题解决:React + Three.js 中 this.renderer 未定义报错

核心问题是**animate 方法的 this 上下文丢失**:当 requestAnimationFrame 调用 this.animate 时,this 不再指向 ThreeViewer 实例,导致访问 this.renderer 时抛出未定义错误。

以下是三种可行的修复方案:

方案1:构造函数内绑定 this

在 ThreeViewer 的构造函数中,手动将 animate 方法的 this 绑定到当前实例:

export class ThreeViewer {
  constructor(canvasRef) {
    // ... 原有代码 ...
    this.camera.position.z = 5;
    // 新增绑定
    this.animate = this.animate.bind(this);
    this.animate();
  }
  animate() {
    this.renderer.render(this.scene, this.camera);
    requestAnimationFrame(this.animate);
  }
}

方案2:使用箭头函数定义 animate

箭头函数会自动继承外层上下文的 this,直接修改 animate 的定义方式:

export class ThreeViewer {
  constructor(canvasRef) {
    // ... 原有代码 ...
    this.animate();
  }
  // 改为箭头函数
  animate = () => {
    this.renderer.render(this.scene, this.camera);
    requestAnimationFrame(this.animate);
  }
}

方案3:在 requestAnimationFrame 中用箭头函数包裹调用

修改 animate 内的 requestAnimationFrame 调用,通过箭头函数确保 this 指向正确:

export class ThreeViewer {
  constructor(canvasRef) {
    // ... 原有代码 ...
    this.animate();
  }
  animate() {
    this.renderer.render(this.scene, this.camera);
    // 用箭头函数包裹,确保this指向实例
    requestAnimationFrame(() => this.animate());
  }
}

完整修复后的代码示例(以方案2为例)

import React from 'react';
import * as THREE from 'three';

export class ThreeViewer {
  constructor(canvasRef) {
    this.canvas = canvasRef;
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

    this.renderer = new THREE.WebGLRenderer({ canvas: canvasRef, preserveDrawingBuffer: true });
    this.renderer.setSize(window.innerWidth, window.innerHeight);

    const geometry = new THREE.BoxGeometry(1, 1, 1);
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    const cube = new THREE.Mesh(geometry, material);
    this.scene.add(cube);
    this.camera.position.z = 5;
    this.animate();
  }
  
  animate = () => {
    this.renderer.render(this.scene, this.camera);
    requestAnimationFrame(this.animate);
  }
}

export default class ObjectViewer extends React.Component {
  constructor(props) {
    super(props);
    this.canvas = React.createRef();
  }

  componentDidMount() {
    const canvas = this.canvas.current;
    this.threeViewer = new ThreeViewer(canvas);
  }
  
  render() {
    return <canvas id="3dviewer" ref={this.canvas}></canvas>;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:42:29