Phase 11 · part: Saddle and seat post
React Three Fiber
Write three.js scenes as React components: JSX objects, useFrame without re-renders, events, drei helpers, Suspense loading, and the showroom rebuilt in React.
React Three Fiber (R3F) is a React renderer for three.js. You describe the scene as JSX, <mesh>, <boxGeometry>, <meshStandardMaterial>, and R3F creates the real three.js objects and keeps them in step with your state. This phase teaches what it does, what it leaves to you, and the mistakes that make R3F scenes slow.
You learn the Canvas and the JSX rules, animation with useFrame (and why setState in it is the classic mistake), pointer and keyboard events, the drei helper library and what each helper hides, and loading models with Suspense and error boundaries.
At the end the showroom is rebuilt in React: the loaded bike, lights, stand and orbit controls, a colour picker in React state that repaints the frame, and the bike's new part, the seat post and saddle.
Phase 11 · the brief from Lumen
Kofi, frontend engineer at Lumen Bikes
“The colour picker, the price panel and the part list are all React. The showroom is plain three.js. Every colour change crosses a wall.”
The Lumen website is a React app. Kofi's showroom so far is plain three.js, and each time a customer picks a colour, a small bridge of event listeners tells the three.js code to change a material. It works, but every new button means another listener, and the state lives in two places.
R3F lets the 3D scene live in the same component tree as the buttons. The colour is one useState value. The picker and the paint read the same variable, and there is nothing to keep in step.
Ama also asks for a saddle. Kofi adds it as a few lines of JSX. By the end of the phase, react.html shows the whole showroom in React, next to the plain version, so Kofi can compare them.
At this station
You will learn
- Turn a three.js scene into JSX and say what R3F creates for each tag
- Animate with useFrame and refs, without re-rendering React 60 times a second
- Handle clicks and keys, load a model with Suspense, and show an error when it fails
- Rebuild the showroom in React, with a colour picker and the saddle
You write code in
In your lumen-3d project (npm run dev), now with React (src/react/), and in the editor on this page
Files you touch
- package.json
- vite.config.js
- react.html
- src/react/main.jsx
- src/react/App.jsx
- src/react/Bike.jsx
Work order · 7 steps
- 11.1Why React Three FiberR3F writes the same three.js objects as JSX and keeps them in step with React state. It does not wrap or hide three.js: every tag is a real three.js class, and the version rule is fiber 9 with React 19. 19 min 2 live scenes
- 11.2The Canvas and JSX ObjectsInside
<Canvas>, each lowercase tag makes a three.js object. Constructor arguments go inargs, nested properties use dashes (position-x), arefgives you the real object, and R3F hooks only work inside the Canvas. 21 min 3 live scenes - 11.3useFrame and StateAnimate through refs inside
useFrame, not throughsetState: a state change re-renders the component every frame. Usedeltafor speed,invalidatewithframeloop="demand"to draw only when needed, and zustand for shared state. 20 min 2 live scenes - 11.4Events in R3FMeshes take
onClickandonPointerOverprops. R3F raycasts for you and calls the handler of every object under the pointer, nearest first, until one callsstopPropagation(). Keyboard input comes from drei'sKeyboardControls. 21 min 2 live scenes - 11.5drei Helpersdrei is a shelf of ready-made R3F parts: controls, environments, shadows, HTML labels, loaders. Each one is plain three.js underneath. Know what each adds to the scene, because some quietly add work to every frame. 20 min 2 live scenes
- 11.6Suspense and Loading in R3F
useGLTFsuspends the component until the model is ready.<Suspense fallback>shows something meanwhile,preloadstarts early, and an error boundary turns a failed load (a 404) into a message instead of a blank canvas. 19 min 2 live scenes - 11.7Build: The Configurator in ReactbuildThe showroom is rebuilt in React Three Fiber at
react.html: the loaded bike, lights, stand and orbit controls, loading and error states, and a colour picker in React state that repaints the frame. The bike gains its seat post and saddle. 23 min 1 live scene
Quality control · 5 tests
Build it yourself, press Check, and the page tests the scene you made: what is in it, where it sits, what it costs the GPU.
crate to the Canvas: a 1 × 1 × 1 box in Lumen orange #ff6b2c, standing on the floor (its bottom at y = 0).BeginnerQC-02Spin without stateThe spinner works, but React renders it on every frame. Rewrite it so it spins through a ref in useFrame, with no useState, and renders only once or twice.BeginnerQC-03Stop the clickA crate stands in front of a wall, and both count clicks in window.hits. A click in the middle of the canvas should reach only the crate. Fix it.IntermediateQC-04Load with a fallbackThe bike loads, and until it does the canvas is empty. Add a <Suspense> around it with a fallback: a mesh named loading. When the bike has arrived, the loading mesh must be gone.IntermediateQC-05Add the saddleThe bike has no saddle. Add a group named saddle with at least two meshes (a post and a seat) above the seat tube: the group's centre at x between -0.25 and 0, and y between 0.9 and 1.1.Intermediate