React-Three-Fiber General Pattern?

tldr; Is it possible to access the state of Canvas outside of Canvas?

Hi all, I am currently deep diving into React-Three-Fiber and I’m a bit confused on how to structure my project. I’ve looked at several examples within code sandbox as well as the React-Three-Fiber documentation and have come up with the structure below.

The general issue I have with the pattern below is that each component has a reference to the state of Canvas. This seems like it could get messy if I’m directly using something like state.scene.getObjectByName('cube-1') since this can be referenced from any Threejs Object component, a different component could also be calling state.scene.getObjectByName('cube-1') and manipulating the Cube.

Perhaps I’m thinking of this in the wrong way, but what I’d really like to do is have one component handle all of the direct interfacing with the Threejs canvas state. Originally I had thought of doing this from within the Component that creates the Canvas tag. However, doing so results in an error message that ref cannot be called from outside Canvas. This makes sense as the ref for Three is not available outside of Canvas. My thought now is to create a single component that is dedicated accessing the Threejs state. So for examples there could be multiple components that have various types of boxes. None of those components would use the useFrame hook and instead all per frame manipulations would be done within the single component I’ve described.

This is an open ended question and I don’t think there are right answers here unless they pertain to performance. I’m just trying to get some opinions on what the most straight-forward approach is for someone who is accustomed to writing plain Javascript Threejs code.

A single page with Canvas

  <div id="home-three">
      <Header />
      <div id="canvas-container" style={{width: '100%', height: '100%', position: 'fixed', top: '0px', zIndex: '-1'}}>
        <Canvas style={{ background: 'black'}}>
          <Controls />
          <ambientLight intensity={0.1} />
          <directionalLight color="white" position={[-5, 0, -5]} />
          <primitive object={new THREE.AxesHelper(10)} />
          <Box />
        </Canvas>
      </div>
      <Footer />
  </div>

Box Object

const Box = () => {
  const someBox = useRef()
  useFrame(({ clock }) => {
    someBox.current.rotation.x = clock.getElapsedTime()
  })
  return (
    <mesh onPointerEnter={(e) => console.log('in')}
      onPointerLeave={(e) => console.log('out')}
      ref={someBox}>
      <boxGeometry />
      <meshStandardMaterial />
    </mesh>
  )
}