Skip to content

Sharing Objects

Video Lecture

Section Video Links
Sharing Objects Sharing Objects Sharing Objects

Description

In this lesson, instead of using useMemo to cache our objects in the components for re-use, we can move the instances into the parent component, and then pass them down by reference. This will also allow us to re-use the same instances in the child components, rather than creating new copies of each.

./src/Polyhedron.jsx

To begin, delete ./src/Box.jsx and create a new file named ./src/Polyhedron.jsx

Copy/paste the below script into it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { useRef, useState } from 'react'
import { useFrame } from '@react-three/fiber'

export default function Polyhedron({ position, polyhedron }) {
  const ref = useRef()
  const [count, setCount] = useState(0)

  console.log(polyhedron)

  useFrame((_, delta) => {
    ref.current.rotation.x += delta
    ref.current.rotation.y += 0.5 * delta
  })

  return (
    <mesh
      position={position}
      ref={ref}
      onPointerDown={() => {
        setCount((count + 1) % 3)
      }}
      geometry={polyhedron[count]}
    >
      <meshBasicMaterial color={'lime'} wireframe />
    </mesh>
  )
}

./src/App.jsx

Replace the contents of ./src/App.jsx with this below script.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import { Canvas } from '@react-three/fiber'
import Polyhedron from './Polyhedron'
import * as THREE from 'three'

export default function App() {
  const polyhedron = [
    new THREE.BoxGeometry(),
    new THREE.SphereGeometry(0.785398),
    new THREE.DodecahedronGeometry(0.785398),
  ]

  return (
    <Canvas camera={{ position: [0, 0, 3] }}>
      <Polyhedron position={[-0.75, -0.75, 0]} polyhedron={polyhedron} />
      <Polyhedron position={[0.75, -0.75, 0]} polyhedron={polyhedron} />
      <Polyhedron position={[-0.75, 0.75, 0]} polyhedron={polyhedron} />
      <Polyhedron position={[0.75, 0.75, 0]} polyhedron={polyhedron} />
    </Canvas>
  )
}

In ./src/App.jsx, I have created an array of 3 different pre-defined Three.js geometries.

const polyhedron = [
  new THREE.BoxGeometry(),
  new THREE.SphereGeometry(0.785398),
  new THREE.DodecahedronGeometry(0.785398),
]

In the JSX where the Polyhedron components are declared, I also add an extra prop named polyhedron passing in the polyhedron array.

<Polyhedron ... polyhedron={polyhedron} />

Also, remember that array indexes are 0 based. So asking for 0 would give me the first, and asking for 1 gives me the second and so on.

Also note that I didn't wrap the polyhedron array in a useMemo. This is because the App component itself never re-renders in this small application. If App ever became more sophisticated that it had some state or props changes while running, then you could consider using useMemo to cache the polyhedron array instances.

Working Example

<>
Sharing Objects sbedit.net
userData threejs.org
Destructuring Assignment developer.mozilla.org
Lifting State Up reactjs.org

GitHub Branch

git clone https://github.com/Sean-Bradley/React-Three-Fiber-Boilerplate.git
cd React-Three-Fiber-Boilerplate
git checkout sharingObjects
npm install
npm start

Comments