<Canvas /> and the Render Loop in React Three FiberIn React Three Fiber (R3F), the <Canvas> component is the cornerstone of your 3D scene. It acts as the entry point and a portal into Three.js, rendering Three.js elements rather than standard DOM elements. It also plays a crucial role in managing the render loop, abstracting away much of the underlying Three.js setup.
<Canvas> ComponentWhen you use the <Canvas> component, R3F automatically sets up several essential elements for your 3D scene:
WebGLRenderer to handle the rendering of your 3D scene.onPointer props, enabling interactivity.The <Canvas> component stretches to 100% of its parent container, so you need to ensure its parent has defined dimensions for the canvas to be visible.
In traditional Three.js, you would typically set up your own animation loop using requestAnimationFrame. R3F abstracts this away, providing an automatic render loop by default.
useFrame Hook: The useFrame hook is a core part of interacting with the render loop. It allows you to execute code on every rendered frame, which is useful for animations, updating controls, and other continuous effects. The callback function provided to useFrame receives the current state of the scene and a delta value (the time elapsed since the last frame).frameloop and invalidateFrameloop): While R3F defaults to continuous rendering, you can control the render mode for performance optimization. You can set the frameloop prop on the <Canvas> component to 'always', 'demand', or 'never'. Setting invalidateFrameloop to true on the <Canvas> component will make it render only when changes are detected (e.g., prop changes), rather than continuously. This is known as "render on demand" and can be beneficial for performance in static scenes.renderPriority greater than zero to the useFrame hook, R3F will disable automatic rendering, and you become responsible for manually triggering renders.This is a conceptual example showing how a basic R3F setup looks. Note that this requires a React environment to run.
import React, { useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
function Box(props) {
const meshRef = useRef();
useFrame(() => {
if (meshRef.current) {
meshRef.current.rotation.x += 0.01;
meshRef.current.rotation.y += 0.01;
}
});
return (
<mesh {...props} ref={meshRef}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={'orange'} />
</mesh>
);
}
export default function App() {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
);
}