React Three Fiber Hooks

Starter pack

In this lesson, we will discover what are useThree and useFrame hooks provided by React Three Fiber, how and when to use them.

useThree

useThree gives access to the state model which contains the default renderer, the scene, camera, the viewport size, and so on.

While I will explain each state properties that we will use at the appropriate time, you can find the full list of properties in the documentation.

To use it, we need to import it from @react-three/fiber, and then call it inside our component:

import { Canvas, useThree } from "@react-three/fiber";
// ...

const Cube = (props) => {
  const { camera } = useThree();
  // ...
};

// ...

While this way of using useThree works, it will cause the component to re-render on other values changes than the ones we got from destructuring.

Instead we can use the selector pattern to only get the values we need:

import { Canvas, useThree } from "@react-three/fiber";

const Cube = (props) => {
  const camera = useThree((state) => state.camera);
  // ...
};

This way, the component will only re-render when the camera value changes.

Keep in mind that threejs internal values are not reactive. If the camera.position changes, the component won't re-render. (Fortunately)

Now we have access to the camera we can modify the fov (field of view) to zoom in or out:

// ...

const Cube = (props) => {
  const camera = useThree((state) => state.camera);

  const updateFov = (fov) => {
    camera.fov = fov;
    camera.updateProjectionMatrix();
  };

  useControls("FOV", {
    smallFov: button(() => updateFov(20)),
    normalFov: button(() => updateFov(42)),
    bigFov: button(() => updateFov(60)),
    hugeFov: button(() => updateFov(110)),
  });

  // ...
};

// ...

Notes:

  • the updateProjectionMatrix method is required to tell threejs that the camera has changed and needs to be updated.
  • by passing a string value as a first parameter to useControls we can group properties by folder.

Our camera Field of View is correctly updated from the controls

useFrame

Threejs is a render-loop based library. It means that what we see on the screen is the result of a loop that renders the scene on every frame. As a video is a succession of images, a 3D scene is a succession of frames.

useFrame hook allows us to execute code on every rendered frame, like running effects, updating controls, and animations.

When targeting 60fps, the callback will be invoked 60 times per second.

End of lesson preview

To get access to the entire lesson, you need to purchase the course.