Reusable components and props

Back to Modules

Reusable Components and Props in React Three Fiber

React Three Fiber (R3F) leverages React's component-based architecture to create and manage Three.js scenes, making it easy to build reusable 3D components and manage their properties using props.

Reusable Components in React Three Fiber

In R3F, you define 3D objects and their behaviors as standard React components. This allows you to encapsulate Three.js logic, state, and interactions within self-contained units that can be reused throughout your application.

For example, instead of manually creating a THREE.Mesh and its geometry and material in imperative Three.js code, you can define a Box component that renders a mesh with a box geometry and a standard material. This component can then be instantiated multiple times with different properties.

Props in React Three Fiber

Props in R3F function identically to props in standard React. They are used to pass data and attributes from a parent component to a child component, allowing you to customize instances of your reusable 3D components.

How Props are Typically Used:

  1. Standard Properties: Most Three.js object properties (like position, scale, rotation, color, intensity for lights, etc.) can be passed directly as props to their corresponding JSX elements. R3F automatically maps these props to the underlying Three.js object's properties.
  2. Constructor Arguments (args prop): For Three.js objects that require arguments during their instantiation (e.g., new THREE.BoxGeometry(width, height, depth)), R3F uses a special args prop. This prop accepts an array of values that are passed directly to the Three.js constructor.
  3. Custom Props: You can define your own custom props for your reusable R3F components, just like in any React component. These props can then be used to control the appearance, behavior, or any other aspect of your 3D object.

Example of a Reusable Component with Props

Here's a simple example of a reusable Box component that accepts position, color, and rotationSpeed as props. Note that this requires a React environment to run.

import React, { useRef, useState } from 'react';
import { Canvas } from '@react-three/fiber';

// Reusable Box component
function Box(props) {
  const meshRef = useRef();
  const [hovered, setHover] = useState(false);
  const [active, setActive] = useState(false);

  useFrame((state, delta) => {
    if (meshRef.current) {
      meshRef.current.rotation.x += delta * (props.rotationSpeed || 1);
      meshRef.current.rotation.y += delta * (props.rotationSpeed || 1);
    }
  });

  return (
    <mesh
      {...props} // Spread all other props (like position) onto the mesh
      ref={meshRef}
      scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
      onClick={() => setActive(!active)}
      onPointerOver={() => setHover(true)}
      onPointerOut={() => setHover(false)}
    >
      <boxGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? 'hotpink' : props.color} />
    </mesh>
  );
}

// App component using the reusable Box
export default function App() {
  return (
    <Canvas>
      <ambientLight intensity={0.5} />
      <pointLight position={[10, 10, 10]} />
      <Box position={[-1.2, 0, 0]} color="orange" rotationSpeed={2} />
      <Box position={[1.2, 0, 0]} color="purple" rotationSpeed={0.5} />
    </Canvas>
  );
}