Threejs 和 Reactjs - 清理三个代码的正确方法

Joe*_*e C 6 three.js reactjs

我有一个 json 文件,我将其加载到 Three.js ObjectLoader 中,然后将其渲染在屏幕上 - 它会旋转,并且我可以根据我单击的颜色来更改其颜色 - 没什么大不了的。

我有一个显示产品列表的列表页面http://domain.com/products。我单击产品标题,然后转到http://domain.com/products/product-name显示 THREEjs 渲染的页面。

问题是我不知道如何处理三号的清理工作。据我所知,他们componentWillUnmount()负责处理清理工作。我应该在其中放置什么componentWillUnmount()才能清理任何 webGL 上下文,或释放内存,或清理任何孤立的对象?

我尝试过的一些事情:

  • 如果我将 中的所有变量设置为 null componentWillUnmount(),然后返回页面http://domain.com/products,我会一遍又一遍地收到错误customize-bow.js:171 Uncaught TypeError: Cannot read property 'render' of null- 这意味着 window.requestAnimationFrame() 尚未取消。

  • 如果我没有componentWillUnmount(),我不相信内存被清除

如果路由加载新组件和新 DOM,webGL 不会被清除,这是怎么回事?关于如何处理这个问题有什么想法吗?

这是代码:

import React from 'react'
import BowDetails from './bow-details'
import * as THREE from 'three'
import axios from 'axios'
var OBJLoader = require('three-obj-loader')(THREE)
var OrbitControls = require('three-orbit-controls')(THREE)

export default class CustomizeProduct extends React.Component {
  constructor (props) {
super(props)

this.state = {
  progress: 0,
  colorToSet: '000000',
  rhinoColors: [{color_name: 'Loading...', color_value: '#000000', swatch_url:'initial-pic.png'}],
  canvasWidth: 664,
  canvasHeight: 671,
  viewSize: 100,
  aspectRatio: function () { return (this.canvasWidth / this.canvasHeight) }
}

this.renderer = new THREE.WebGLRenderer({antialias: true})
this.scene = new THREE.Scene()
this.textureLoader = new THREE.TextureLoader()
this.camera = new THREE.OrthographicCamera(-this.state.aspectRatio() * this.state.viewSize / 2, this.state.aspectRatio() * this.state.viewSize / 2, this.state.viewSize / 2, -this.state.viewSize / 2, -40, 80)
this.objectLoader = new THREE.ObjectLoader()

this.basicMaterial = new THREE.MeshPhongMaterial({color: 0x000000, emissive: 0x000000, specular: 0x000000, shininess: 4, shading: THREE.SmoothShading})
this.camMaterial = new THREE.MeshPhongMaterial({color: 0x000000, emissive: 0x3c4047, specular: 0x666666, shininess: 1, shading: THREE.SmoothShading})
this.limbMaterial = new THREE.MeshPhongMaterial({color: 0x000000, emissive: 0x000000, specular: 0x666666, shininess: 1, shading: THREE.SmoothShading})
this.object = null
this.riserTextureMaterial = null
}

componentWillReceiveProps (nextProps) {
   // code to update the props once they come in from Redux ...
  }

componentWillUnmount () {
// What do I put in here to clear out the reference, memory to the webGL
var that = this
window.cancelAnimationFrame(that.renderThree)
this.renderer = null
this.scene = null
this.textureLoader = null
this.camera = null
this.objectLoader = null

this.basicMaterial = null
this.camMaterial = null
this.limbMaterial = null
this.object = null
this.riserTextureMaterial = null

this.mouseBow = null
this.clock = null
this.orbitControls = null
}

render () {
return (
// JSX code to render ...
)
}
}
Run Code Online (Sandbox Code Playgroud)