<Environment> from @react-three/drei causes a rerender

So I have a Canvas

<Canvas className="App"
    style={{
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        backgroundColor: "black",
        zIndex: 1}}
    camera={{
        far: 1000,
        near: 0.01,
        fov: 75,
        position: [0, 0, 0],  
        aspect: innerWidth / innerHeight,
        type: 'PerspectiveCamera'
    }}
>
    <Environment preset="sunset" />
    <Floaters params={floatersParams}/>
<Canvas/>

And in my Floaters I have a console statement to let me know when it mounts

const Floaters = ({params}) => {
    console.log("Floaters call")
    // ... rest of code
}

When I include <Environment preset="sunset" /> in my set up, I see the console message appear twice

What I don’t understand is why this is happening

For example I tested things out using <Stars/> from drei and it did not trigger a rerender

<Canvas className="App"
    style={{
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        backgroundColor: "black",
        zIndex: 1}}
    camera={{
        far: 1000,
        near: 0.01,
        fov: 75,
        position: [0, 0, 0],  
        aspect: innerWidth / innerHeight,
        type: 'PerspectiveCamera'
    }}
>
    <Stars radius={100} depth={50} count={7000} factor={1} saturation={0} speed={0}/>
    <Floaters params={floatersParams}/>
<Canvas/>

env loads an async resource, sunset.hdri though suspense. everything inside canvas will unmount and mount again once the resource has finished loading. that’s generally how react suspense works. you have full control over it, too. for instance:

<Canvas>
  <Suspense fallback={null}>
    <Environment ... />
  </Suspense>
  <Floaters />

this will show floaters independent of env’s loading state. what this allows you to do is to manage your async tasks.

1 Like