Combine React-three-fiber and threeJS code

Hello,

I have a plain ThreeJS code and I would like to be able to combine it with code in React-three-fiber, React-three-Drei, and other React libraries. Is there any way to easily combine all this? Or would it be best if I translate the ThreeJS code to React-three-fiber? Knowing that the code is quite long and I’m not sure how to go about translating everything.

It’s definitely possible. There’s no way to know if it’s a good idea or not without seeing your code, however.

Yes, it’s not ideal, but sadly I don’t think I’m allowed to post my code.
Maybe if someone has links to project examples combining both, it could help?

function Vanilla(props) {
  const [scene] = useState(() => new THREE.Scene())
  useLayoutEffect(() => {
    const geometry = new THREE.BoxGeometry()
    const material = new THREE.MeshBasicMaterial()
    const mesh = new THREE.Mesh(geometry, material)
    scene.add(mesh)
    // ...
    return () => void scene.dispose()
  }, [])
  return <primitive object={scene} {...props} />
}

...
<Vanilla position={[1, 2, 3]} />

<primitive object={...} /> can mount any existing, foreign threejs object into the scene. But watch out for memory, you are now being responsible to clean up after yourself. useLayoutEffect is called before the component renders on screen, good place to handle imperative logic, and it has a clean-up phase (the return).

Generally it is best to do as much as you can declaratively. Try to break out parts and re-use them. You’ll soon figure that you’re reducing the original code and in the long run it will only help maintenance and sanity overall.

1 Like

let’s say I have an orbitcontrol from fiber and want to manipulate it with plain js code…

import { OrbitControls} from "@react-three/drei";

function MyComponent() {
	return (
		<Fragment>
			<OrbitControls target={[0, 0.35, 0]} maxPolarAngle={1.45} />
			<PerspectiveCamera makeDefault fov={50} position={[3, 2, 5]} />
               </Fragment>
}

const myCustomRaycasterFunction = (renderer, scene, camera, OrbitControls, box) => {
       //how to access to renderer, scene, camera or a early created box mesh?
}

function App() {
	return (
		<Suspense fallback={null}>
			<Canvas shadows>
				<MyComponent/>
			</Canvas>
		</Suspense>
	);
}

export default App;

what I programmed in plain js/three.js is a “lookAt()” function… where the MapControls looks at the clicked object and highlights this… I have no idea how to mount that code for three/fiber.

Fiber experts might give you even better options but you can generally use hooks to to run code alongside your components. useEffect by default runs every time the component rerenders. useFrame runs every frame (and is a native r3f hook).

These are react patterns and not r3f-specific patterns. Getting familiar with them early is going to pay back later on so I highly recommend spending some time with them!

Thank you.
But I still don’t know how to access a component of fiber which is inserted like to the jsx.

Ah, right! That’s another react hook called useRef. It’s quite similar to giving an element an ID in pure HTML. If you take a look at some of the examples from the fiber documentation you’ll see it in use.

1 Like

ok I know useRef() but I thought it just gives access to the DOM element but not to the OrbitControls JavaScript Object. So you say in this case using useRef() on fiber objects gives access to the actual js object? I have to test it.