Set default camera in React Three Fiber
React Three Fiber supports all Three.js camera types, but it does some hidden setup such that simply instantiating a camera isn’t enough to render using it.
Unfortunately, there doesn’t seem to be a way to do this declaratively. React Three Fiber provides a hook useThree
for querying and manipulating the internal state, such as the current camera.
The solution is to use React’s useLayoutEffect
hook to set the active React Three Fiber camera when the camera component mounts, keeping a reference to the previous camera in the closure so it can be restored when it unmounts.
import * as THREE from "three";
import { useLayoutEffect } from "react";
function OrthographicCamera() {
const camera = useRef<THREE.OrthographicCamera>(null);
const set = useThree((three) => three.set);
const prevCamera = useThree((three) => three.camera);
useLayoutEffect(() => {
// if there's no current camera ref, exit early
const current = camera.current;
if (!current) return;
// store the previous camera to restore it when the effect cleans up
const prev = prevCamera;
// set the react three fiber camera to the current camera ref
set(() => ({ camera: current }));
// restore the previous camera when the effect cleans up
return () => set(() => ({ camera: prev }));
// don't include `prevCamera` in the dependency array so the effect keeps a reference to the default
}, [camera, set]);
return <orthographicCamera ref={camera} />;
}
The drei library (a bunch of utilies for React Three Fiber) includes something like this in the source code for their OrthographicCamera
component.