Skip to content

Common Gotchas

  • <Canvas /> fills its parent, so give the parent a height or the scene can disappear.
  • args are constructor arguments. If they change, the underlying object can be recreated.
  • Continuous animation should usually mutate refs in useFrame, not update React state every frame.
  • R3F event handlers already perform the common raycasting work for you.
  • Lowercase JSX primitives usually map to Three.js classes. Uppercase component names are usually your own React components or library abstractions.
  • You usually do not call renderer.render(scene, camera) yourself inside <Canvas />.
  • A material that needs light in Three.js still needs light in R3F.
  • Loading helpers in R3F still rely on Three.js loaders and asset formats under the hood.

Translate the code back into the underlying scene graph:

  1. What objects are being created?
  2. Which object owns which child?
  3. Which values are constructor arguments?
  4. Which values are mutable updates over time?

That four-question pass usually clears up most confusion.