import * as THREE from 'three';
export default class ViewGL{
constructor(canvasRef) {
this.scene = new THREE.Scene();
this.renderer = new THREE.WebGLRenderer({
canvas: canvasRef,
antialias: false,
});
// Create meshes, materials, etc.
this.scene.add(myNewMesh);
this.update();
}
// ******************* PUBLIC EVENTS ******************* //
updateValue(value) {
// Whatever you need to do with React props
}
onMouseMove() {
// Mouse moves
}
onWindowResize(vpW, vpH) {
this.renderer.setSize(vpW, vpH);
}
// ******************* RENDER LOOP ******************* //
update(t) {
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(this.update.bind(this));
}
}
This way you can communicate between the React component and your plain Three.js file. React loves building & destroying components, so my only advice is to avoid this because WebGL and Three.js can consume a lot of memory if you re-build it multiple times. I prefer to just hide & show it after it’s been constructed, that way you avoid all WebGL re-building overhead. Only use componentWillUnmount if you’re 100% sure it won’t be re-built again.
is there a reason why you’d do that w/o r3f? i see no benefit, all you’d do is create a split between declarative react and imperative three. r3f is not a wrapper or a binding, it just expresses three declaratively just like you express divs and spans via react-dom. imo what you’re doing is the same as making a component that suddenly builds part of the dom with queryselector and innerhtml.
I actually use a hybrid setup. I generally have a basic r3f setup for ease of UI integration, and then simply use useFrame() when I need to use more “regular” 3js code. This works perfectly, and gives me the best of both worlds:
r3f allows me quick iterations and easy basic setup (usually have a Canvas/debug controls & helpers all done using r3f)
The useFrame() approach lets me do “regular” 3js stuff, preventing all my code being tied to both 3js and react.
Personally, this works for me quite well, but I guess it is more a matter of taste then anything else. Integrating 3js into react is quite complex if you want to do it right, and I’m happy to leave that to r3f
I made a little boilerplate here for that purpose (I tend to prefer the JS approach over the react-three-fiber approach as I can move a little quicker without the JSX abstraction).