Skip to content

Loading Models and Textures

Use the same loader mental model, but let useLoader align resource fetching with React rendering.

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 { Canvas } from '@react-three/fiber';
import { useState } from 'react';
import { CanvasTexture } from 'three';
function createCheckerTexture() {
const canvas = document.createElement('canvas');
canvas.width = 128;
canvas.height = 128;
const context = canvas.getContext('2d');
if (!context) {
return new CanvasTexture(canvas);
}
context.fillStyle = '#0f172a';
context.fillRect(0, 0, canvas.width, canvas.height);
for (let y = 0; y < 8; y += 1) {
for (let x = 0; x < 8; x += 1) {
context.fillStyle = (x + y) % 2 === 0 ? '#38bdf8' : '#f8fafc';
context.fillRect(x * 16, y * 16, 16, 16);
}
}
context.strokeStyle = '#f97316';
context.lineWidth = 6;
context.strokeRect(3, 3, canvas.width - 6, canvas.height - 6);
const texture = new CanvasTexture(canvas);
texture.needsUpdate = true;
return texture;
}
function TexturedBox() {
const [texture] = useState(() => createCheckerTexture());
return (
<mesh>
<boxGeometry args={[1.8, 1.8, 1.8]} />
<meshStandardMaterial map={texture} />
</mesh>
);
}
export default function App() {
return (
<div style={{ height: '100vh', background: '#0f172a' }}>
<Canvas camera={{ fov: 50, position: [0, 0, 4] }} dpr={[1, 2]}>
<color attach="background" args={['#0f172a']} />
<ambientLight intensity={0.4} />
<directionalLight position={[2, 3, 4]} intensity={1.5} />
<TexturedBox />
</Canvas>
</div>
);
}

Live preview

What Changed

  • new THREE.TextureLoader().load(...) becomes useLoader(TextureLoader, url).
  • The loaded texture gets passed into the material as a prop.
  • The example uses textures, but the same idea extends to models with loaders like GLTFLoader.
  • You are still using Three.js loaders. R3F is helping them fit into component rendering.

If a Three.js example says “load an asset, then create objects that use it,” the R3F version is usually “call a loader hook, then return JSX that consumes the loaded resource.”