score:1

Accepted answer

@juliomalves comment above was the answer. Thank you. I was looking in all the wrong places.

Here is the updated code, split into a page and a dynamically loaded component (with some new content for visibility).

import dynamic from 'next/dynamic'
import styled from "styled-components"

const Scene = dynamic(
  () => import('./scene'),
  { ssr: false }
)

export default function App() {
  return (
    <div>
      <ModelDiv>
          <Scene/>
      </ModelDiv>
    </div>
  )
}

const ModelDiv = styled.div`
  display: block;
  background-color: lightblue;
    width: 100%;
  height: 100vh;
`;

The corresponding component in scene.js:

import { Canvas } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'

export default function Scene() {
    return (
            <Canvas>
                <ambientLight intensity={1} />
                <directionalLight position={[0, 1, 5]} intensity={1} />
                <OrbitControls />
                <mesh>
                    <boxGeometry args={[1, 1, 1]} />
                    <meshStandardMaterial color="yellow" />
                </mesh>
            </Canvas>
    )
}

score:0

By running useLayoutEffect on the server you can potentially send different html content than the one that the app will produce when running on the client for the first time, hence the warning. One way to fix this is not to render the component that uses useLayoutEffect on the server.

You can do this by checking if the window object is defined. When it is defined it means that your code is running on the client, and only then you should render your canvas component.


Related Query

More Query from same tag