我有一个json文件,我加载到Three.js ObjectLoader中,它在屏幕上呈现 - 它旋转,我可以根据我点击的颜色更改颜色 - 没什么大不了的。
我有一个列表页面,其中显示了产品http://domain.com/products
的列表。我点击产品标题,然后路由到显示THREEjs渲染的http://domain.com/products/product-name
。
问题在于我不知道如何处理三人的清理工作。我知道componentWillUnmount()
负责处理清理工作。我可以在componentWillUnmount()
中添加什么来清理任何webGL上下文,释放内存或清理任何孤立的对象?
我尝试过的一些事情:
如果我在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 ...
)
}
}