简体   繁体   中英

TypeError: element.setAttribute is not a function (React Native / Three.js)

I have been struggling with drei (a collection of helpers for react three fiber) when it comes to trying to make it run on device (Android / Expo). Running it on web-browser works but device always returns the Exception error:

TypeError: element.setAttribute is not a function. (In 'element.setAttribute(eventName, 'return;')', 'element.setAttribute' is undefined)

This refers to line 321 of \\node_modules\\metro\\src\\lib\\polyfills\\require.js This line is:

factory(

            global,
            metroRequire
            metroImportDefault,

etc

I am using the default code:

import React, { useRef, useState } from "react";
import { StyleSheet, View } from "react-native";
import { Canvas, useFrame } from "react-three-fiber";
import { Sky } from '@react-three/drei'; // this causes the error


function Box(props) {
  // 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(() => {
    if (mesh && mesh.current) {
      mesh.current.rotation.x = mesh.current.rotation.y += 0.01;
    }
  });

  return (
    <mesh
      {...props}
      ref={mesh}
      scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
      onClick={(e) => setActive(!active)}
      onPointerOver={(e) => setHover(true)}
      onPointerOut={(e) => setHover(false)}
    >
      <boxBufferGeometry attach="geometry" args={[1, 1, 1]} />
      <meshStandardMaterial
        attach="material"
        color={hovered ? "blue" : "red"}
      />
    </mesh>
  );
}

export default function App() {
  return (
    <View style={styles.container}>
      <Canvas>
        <ambientLight />
        <Sky />
        <pointLight position={[10, 10, 10]} />
        <Box position={[-1.2, 0, 0]} />
        <Box position={[1.2, 0, 0]} />
      </Canvas>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "black",
  },
});

import { Sky } from '@react-three/drei' is the part that causes the error, and any drei reference causes this. If I remove that and the reference to it on export default function App(), the project works perfectly on device. The project does work on browser even with drei.

I kindly appreciate advice or just a solid confirmation that drei does not work on device.

Element.setAttribute() is a method used by HTMLElements . You can read about it here . The reason it works on browser is because it probably creates an element, like a <div> , or <img> or something, and then it calls setAttribute on it. However, when you try to export to device, that function is not available because it's not a full HTML browser, and it doesn't have all its capabilities.

When you create an element, it returns undefined and undefined.setAttribute() is not a function.

I think you're going to have to go into the source code of drei and look for where it's happening to see if you can create a copy of that module and remove the lines where it attempts to create an HTMLElement without breaking the build.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM