DEV Community

loading...

Compare React with three.js and react-three-fiber

Koji (he/him)
Never lose curiosity Software Engineer in NYC/Research Resident@NYU-ITP18-19 Mostly I work with typescript, javascript, react, and python. code to do something weird/useless/helpful
・1 min read

Alt Text

The following codes show the same output like above.

With threejs

import React from 'react';
import './App.css';
import * as THREE from 'three';

function App() {
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.innerHTML = '';
  document.body.appendChild(renderer.domElement);

  const geometry = new THREE.BoxGeometry();
  const material = new THREE.MeshBasicMaterial({
    color: 'blue',
  });

  camera.position.z = 5;

  const cube = new THREE.Mesh(geometry, material);

  scene.add(cube);

  const animate = () => {
    requestAnimationFrame(animate);
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    renderer.render(scene, camera);
  }

  animate();

  window.addEventListener('resize', ()=>{
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth/window.innerHeight;
    camera.updateProjectionMatrix();
  })

  return(
    null
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

With react-three-fiber

GitHub logo pmndrs / react-three-fiber

🇨🇭 A React renderer for Three.js

react-three-fiber

Version Downloads Twitter Discord Open Collective ETH BTC

react-three-fiber is a React renderer for threejs.

npm install three @react-three/fiber
Enter fullscreen mode Exit fullscreen mode

Why?

Build your scene declaratively with re-usable, self-contained components that react to state, are readily interactive and can tap into React's ecosystem.

Does it have limitations?

None. Everything that works in threejs will work here without exception.

Can it keep up with frequent updates to threejs?

Yes, because it merely expresses threejs in JSX: <mesh /> becomes new THREE.Mesh(), and that happens dynamically. There is no hard dependency on a particular threejs version, it does not wrap or duplicate a single threejs class.

Is it slower than plain threejs?

There is no additional overhead. Components participate in the renderloop outside of React.

What does it look like?

Let's make a re-usable component that has its own state, reacts to user-input and participates in the render-loop. (live demo).
import ReactDOM from 'react-dom'
import React, {
Enter fullscreen mode Exit fullscreen mode

react-three-fiber has components that allow us to use without creating each instance for scene, camera, material, mesh etc.

import React, { useRef } from 'react';
import './App.css';
import { Canvas, useFrame } from 'react-three-fiber';

const Box = () => {
  const ref = useRef<THREE.Mesh>();
  useFrame((state) => {
    // console.log(state);
    if(ref.current !== undefined) {
      ref.current.rotation.x = ref.current.rotation.y += 0.01;
    }
  });

  return(
    <mesh ref={ref}>
        <boxBufferGeometry />
        <meshBasicMaterial color="blue" />
      </mesh>
  );
}

function App() {
  return(
    <div style={{ height:'100vh', width:'100vh'}}>
      <Canvas style={{ background: 'black'}}>
      <Box />
    </Canvas>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Discussion (0)