3

I'm trying to use the texture for my ThreeJS object. I'm getting error:

index.js:1 Error: Earth suspended while rendering, but no fallback UI was specified.

Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.
    in Earth

Earth.js:

export const Earth = () => {
    const texture = useLoader(THREE.TextureLoader, earthImg)

    return (
        <Suspense fallback={<h1>Loading profile...</h1>}>
            <mesh>
                <sphereBufferGeometry attach="geometry" args={[5, 32, 32]} />
                <meshStandardMaterial attach="material"  roughness={1} fog={false} />
            </mesh>
        </Suspense>
    )
}

index.js:

export default function App() {
    return (
        <Canvas
            style={{height:'100vh',width:'100vw'}}
            camera={{
                position: [0, window.innerWidth / window.innerHeight, 5]
            }}
        >
            <ambientLight intensity={0.5} />
            <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
            <pointLight position={[-10, -10, -10]} />
            <Earth position={[-1.2, 0, 0]} />
        </Canvas>
    )
}
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
Bakr
  • 465
  • 1
  • 6
  • 15
  • 2
    `useLoader()` needs to be called from a component mounted _inside_ `` within the virtual DOM. In other words, the `` needs to wrap ``, not be returned from it. – Patrick Roberts Sep 28 '20 at 16:52
  • also, fallback={

    Loading profile...

    is not valid. h1 is a dom element. if you need dom overlays as a fallback use the drei library (the Html component specifically) https://github.com/pmndrs/drei then you can do `fallback={

    loading

    }`>
    – hpalu Sep 28 '20 at 20:24

1 Answers1

7

The component that useLoader() is called from (<Earth> in this case) needs to be wrapped in a <Suspense>, a suspense fallback cannot be specified from within the component.

Earth.js:

export const Earth = () => {
    const texture = useLoader(THREE.TextureLoader, earthImg)

    return (
        <mesh>
            <sphereBufferGeometry attach="geometry" args={[5, 32, 32]} />
            <meshStandardMaterial attach="material"  roughness={1} fog={false} />
        </mesh>
    )
}

index.js:

export default function App() {
    return (
        <Canvas
            style={{height:'100vh',width:'100vw'}}
            camera={{
                position: [0, window.innerWidth / window.innerHeight, 5]
            }}
        >
            <ambientLight intensity={0.5} />
            <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} />
            <pointLight position={[-10, -10, -10]} />
            <Suspense fallback={<h1>Loading profile...</h1>}>
                <Earth position={[-1.2, 0, 0]} />
            </Suspense>
        </Canvas>
    )
}
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153