Skip to content

Animation Loop to useFrame

Map requestAnimationFrame updates to React Three Fiber's frame hook without turning every tick into React state.

Pinned example stack

react@19.1.1react-dom@19.1.1@react-three/fiber@9.3.0three@0.180.0

Exact Conversion

Switch between the React Three Fiber and Three.js examples, then test the R3F result in the live preview below.

React Three Fiber
import { useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
function SpinningCube() {
const meshRef = useRef(null);
useFrame(() => {
if (!meshRef.current) return;
meshRef.current.rotation.x += 0.01;
meshRef.current.rotation.y += 0.015;
});
return (
<mesh ref={meshRef}>
<boxGeometry args={[1.5, 1.5, 1.5]} />
<meshStandardMaterial color="#38bdf8" />
</mesh>
);
}
export default function App() {
return (
<div style={{ height: '100vh', background: '#0b1120' }}>
<Canvas camera={{ fov: 60, position: [0, 0, 4] }} dpr={[1, 2]}>
<color attach="background" args={['#0b1120']} />
<directionalLight position={[2, 3, 4]} intensity={1.4} />
<SpinningCube />
</Canvas>
</div>
);
}

Live preview

What Changed

  • requestAnimationFrame(animate) becomes useFrame(...).
  • The mutable object reference moves into useRef.
  • Rotation updates still mutate the underlying Three.js object directly.
  • React state is not the right tool for per-frame transforms like this.

In Three.js, you already mutate the mesh each frame. In R3F, that pattern still exists. The React part is how you declare the scene, not a requirement to drive every animation through component state.