Pmndrs.docs

Render Function

React Three Fiber without the React part

As of version 6 you may use a render function, similar to how react-dom and all the other React renderers work. This allows you to shave off react-dom (~40kb), react-use-measure + resize-observer-polyfill (~5kb) and, if you don't need them, pointer-events (~7kb) (you need to explicitly import events and add them to the config otherwise).

The render functions config has the same options and properties as Canvas, but you are responsible for resizing it. It requires an existing DOM <canvas> object into which it renders.

import React from 'react'
import { render, events } from '@react-three/fiber'

window.addEventListener('resize', () =>
  render(<mesh />, document.querySelector('canvas'), {
    events,
    size: { width: window.innerWidth, height: window.innerHeight },
  }),
)

window.dispatchEvent(new Event('resize'))

To unmount and dispose of all the memory that has been acquired:

import { unmountComponentAtNode } from '@react-three/fiber'

unmountComponentAtNode(document.querySelector('canvas'))

render is depreciated in v8 beta for the new createRoot signature.

import { createRoot } from '@react-three/fiber'

let root

window.addEventListener('resize', () =>
  root = createRoot(document.querySelector('canvas'), {
    events,
    size: { width: window.innerWidth, height: window.innerHeight },
  ).render(<mesh />)
)

window.dispatchEvent(new Event('resize'))

// to unmount
root.unmount()

⚠️ Tree-shaking

New with v8 beta, the underlying reconciler no longer pulls in the THREE namespace automatically.

This enables a granular catalogue which also enables tree-shaking via the extend API:

import { extend, createRoot } from '@react-three/fiber'
import { Mesh, BoxGeometry, MeshStandardMaterial } from 'three'

extend({ Mesh, BoxGeometry, MeshStandardMaterial })

createRoot(canvas).render(
  <>
    <mesh>
      <boxGeometry />
      <meshStandardMaterial />
    </mesh>
  </>,
)

There's an official babel plugin which will do this for you automatically:

// In:

import { createRoot } from '@react-three/fiber'

createRoot(canvasNode).render(
  <mesh>
    <boxGeometry />
    <meshStandardMaterial />
  </mesh>,
)

// Out:

import { createRoot, extend } from '@react-three/fiber'
import { Mesh as _Mesh, BoxGeometry as _BoxGeometry, MeshStandardMaterial as _MeshStandardMaterial } from 'three'

extend({
  Mesh: _Mesh,
  BoxGeometry: _BoxGeometry,
  MeshStandardMaterial: _MeshStandardMaterial,
})

createRoot(canvasNode).render(
  <mesh>
    <boxGeometry />
    <meshStandardMaterial />
  </mesh>,
)