Jonas
Jonas

Reputation: 7915

Access ref of component in another component?

In my component Box I return a mesh which is of type Object3d, I need to get a reference to this object in my Floor component but I haven't figured out a way to do this. I tried to assign another ref in my App component and pass it to Floor but this way I only get {current: undefined}.

How can I reference the mesh ref of Box in another component?

This is how I tried it

export default function App() {

  const box = useRef();

  return (
    <Canvas camera={{ position: [0, 10, 10] }} onCreated={({ scene }) => {
      scene.background = new THREE.Color(0xffffff);
      scene.fog = new THREE.Fog(0xffffff, 0, 750);
    }} >
      <hemisphereLight args={[0xeeeeff, 0x777788, 0.75]} position={[0.5, 1, 0.75]}></hemisphereLight>
      <Box ref={box} position={[0, 10, -30]} />
      <Floor boxRef={box}></Floor>
    </Canvas>
  )
}

function Floor({ boxRef }) {
  const mesh = useRef();

  useFrame(() => {
    // How to use the mesh ref of Box here?????
    console.log(boxRef);
  })

  return (
    <mesh ref={mesh} >
      <planeBufferGeometry args={[2000, 2000]} rotateX={-Math.PI / 2}></planeBufferGeometry>
      <meshStandardMaterial color="#999999"></meshStandardMaterial>
    </mesh>
  )
}

function Box(props) {
  const mesh = useRef()
  
  return (
    <mesh
      {...props}
      ref={mesh}>
      <boxBufferGeometry args={[20, 20, 20]} />
      <meshPhongMaterial color={0x00ff00}></meshPhongMaterial>
    </mesh>
  )
}

Upvotes: 0

Views: 207

Answers (2)

Jonas
Jonas

Reputation: 7915

The solution involved React.forwardRef, this is how I solved it

export default function App() {

  const box = useRef();

  return (
    <Canvas camera={{ position: [0, 10, 10] }} onCreated={({ scene }) => {
      scene.background = new THREE.Color(0xffffff);
      scene.fog = new THREE.Fog(0xffffff, 0, 750);
    }} >
      <hemisphereLight args={[0xeeeeff, 0x777788, 0.75]} position={[0.5, 1, 0.75]}></hemisphereLight>
      <Box ref={box} position={[0, 10, -30]} />
      <Floor boxRef={box}></Floor>
    </Canvas>
  )
}

function Floor({ boxRef }) {
  const mesh = useRef();

  useFrame(() => {
    console.log(boxRef);
  })

  return (
    <mesh ref={mesh} >
      <planeBufferGeometry args={[2000, 2000]} rotateX={-Math.PI / 2}></planeBufferGeometry>
      <meshStandardMaterial color="#999999"></meshStandardMaterial>
    </mesh>
  )
}

const Box = React.forwardRef((props, ref) => {  
  return (
    <mesh
      {...props}
      ref={ref}>
      <boxBufferGeometry args={[20, 20, 20]} />
      <meshPhongMaterial color={0x00ff00}></meshPhongMaterial>
    </mesh>
  )
})

Upvotes: 0

Kimya Khakzad
Kimya Khakzad

Reputation: 223

I guess you should not override ref in Box component and just use {...props}

export default function App() {

  const box = useRef();

  return (
    <Canvas camera={{ position: [0, 10, 10] }} onCreated={({ scene }) => {
      scene.background = new THREE.Color(0xffffff);
      scene.fog = new THREE.Fog(0xffffff, 0, 750);
    }} >
      <hemisphereLight args={[0xeeeeff, 0x777788, 0.75]} position={[0.5, 1, 0.75]}></hemisphereLight>
      <Box ref={box} position={[0, 10, -30]} />
      <Floor boxRef={box}></Floor>
    </Canvas>
  )
}

function Floor({ boxRef }) {
  const mesh = useRef();

  useFrame(() => {
    // How to use the mesh ref of Box here?????
    console.log(boxRef);
  })

  return (
    <mesh ref={mesh} >
      <planeBufferGeometry args={[2000, 2000]} rotateX={-Math.PI / 2}></planeBufferGeometry>
      <meshStandardMaterial color="#999999"></meshStandardMaterial>
    </mesh>
  )
}

function Box(props) {
  
  return (
    <mesh
      {...props}>
      <boxBufferGeometry args={[20, 20, 20]} />
      <meshPhongMaterial color={0x00ff00}></meshPhongMaterial>
    </mesh>
  )
}

Upvotes: 1

Related Questions