Cedric Martens
Cedric Martens

Reputation: 1199

Can't get react-three/fiber to render a canvas in my react-native project

I have some application that has some code with multiple pages. On one page, I want a three canvas.

I have some code like this.

export const MyScreen = ({navigation}) => {
   return (
     <View>
       <SomeHeader navigator={navigation}/>
       <View style={styles.canvas}>
         <MyCanvas/>
       </View>
     </View>
 );

Then I also have this code.

export class MyCanvas extends React.Component {

  render() {
    // This reference will give us direct access to the mesh
    const mesh = useRef()
    // Set up state for the hovered and active state
    const [hovered, setHover] = useState(false)
    const [active, setActive] = useState(false)
    // Rotate mesh every frame, this is outside of React without overhead
    useFrame(() => (mesh.current.rotation.x += 0.01))

    return (
        <Canvas>
          <mesh
            {...props}
            ref={mesh}
            scale={active ? 1.5 : 1}
            onClick={(event) => setActive(!active)}
            onPointerOver={(event) => setHover(true)}
            onPointerOut={(event) => setHover(false)}>
            <boxGeometry args={[1, 2, 3]} />
            <meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
          </mesh>
        </Canvas>
    );
  }
}

which results in this error

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

Aren't the hooks in the body of the function component? I'm confused.

Upvotes: 1

Views: 1930

Answers (1)

Deep
Deep

Reputation: 549

MyCanvas is a class component since it extends React.Component.

In your case, I guess what you want is this:

function MyCanvas() {
  const mesh = useRef()
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)
  useFrame(() => (mesh.current.rotation.x += 0.01))

  return (
    <Canvas>
      <mesh
        {...props}
        ref={mesh}
        scale={active ? 1.5 : 1}
        onClick={(event) => setActive(!active)}
        onPointerOver={(event) => setHover(true)}
        onPointerOut={(event) => setHover(false)}>
        <boxGeometry args={[1, 2, 3]} />
        <meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
      </mesh>
    </Canvas>
  );
}

The React documentation has more details of the same error. https://reactjs.org/warnings/invalid-hook-call-warning.html

Nevertheless, the above error is not related to r3f. But r3f might not work with React Native. There are a few issues on the Github repo and an open PR planned for version 8 release from my initial research https://github.com/pmndrs/react-three-fiber/pull/1384

https://github.com/pmndrs/react-three-fiber/pull/1699

Upvotes: 2

Related Questions