为什么我会收到此 useLayoutEffect 警告(不在测试中)
Why am I getting this useLayoutEffect warning (not in a test)
我有一个新创建的、几乎是空的 next/react/fiber 项目,带有光纤 Canvas。每次编译都会抛出以下警告。
Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
at Canvas (C:\MyLocalFiles\Stratum\repos\cfgnext-updated\node_modules\@react-three\fiber\dist\react-three-fiber.cjs.dev.js:155:3)
这是说明问题的最小示例,其次是 package.json:
import { Canvas } from '@react-three/fiber'
export default function Home() {
return (
<div>
<Canvas>
</Canvas>
</div>
)
}
package.json
{
"name": "cfgnext-updated",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@react-three/drei": "^9.0.1",
"@react-three/fiber": "^8.0.6",
"babel-plugin-styled-components": "^2.0.6",
"next": "12.1.4",
"react": "18.0.0",
"react-dom": "18.0.0",
"styled-components": "^5.3.5"
},
"devDependencies": {
"eslint": "8.12.0",
"eslint-config-next": "12.1.4"
}
}
当我用其他纤维组件填充 Canvas 时,一切似乎都很完美。
谁能告诉我:
- 这实际上是一个合理的警告吗?如果没有
- 有没有办法消除它?
蒂亚,
比尔
通过 运行 useLayoutEffect
在服务器上您可能会发送不同的 html
内容,而不是第一次在客户端 运行 时应用程序将生成的内容时间,因此警告。
解决此问题的一种方法是不在服务器上呈现使用 useLayoutEffect
的组件。
您可以通过检查是否定义了 window
对象来做到这一点。当它被定义时,这意味着你的代码在客户端上是 运行,只有这样你才应该渲染你的 canvas
组件。
@juliomalves 上面的评论就是答案。谢谢你。我一直在寻找错误的地方。
这是更新后的代码,分为一个页面和一个动态加载的组件(包含一些新内容以提高可见性)。
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;
`;
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>
)
}
我有一个新创建的、几乎是空的 next/react/fiber 项目,带有光纤 Canvas。每次编译都会抛出以下警告。
Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
at Canvas (C:\MyLocalFiles\Stratum\repos\cfgnext-updated\node_modules\@react-three\fiber\dist\react-three-fiber.cjs.dev.js:155:3)
这是说明问题的最小示例,其次是 package.json:
import { Canvas } from '@react-three/fiber'
export default function Home() {
return (
<div>
<Canvas>
</Canvas>
</div>
)
}
package.json
{
"name": "cfgnext-updated",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@react-three/drei": "^9.0.1",
"@react-three/fiber": "^8.0.6",
"babel-plugin-styled-components": "^2.0.6",
"next": "12.1.4",
"react": "18.0.0",
"react-dom": "18.0.0",
"styled-components": "^5.3.5"
},
"devDependencies": {
"eslint": "8.12.0",
"eslint-config-next": "12.1.4"
}
}
当我用其他纤维组件填充 Canvas 时,一切似乎都很完美。
谁能告诉我:
- 这实际上是一个合理的警告吗?如果没有
- 有没有办法消除它?
蒂亚, 比尔
通过 运行 useLayoutEffect
在服务器上您可能会发送不同的 html
内容,而不是第一次在客户端 运行 时应用程序将生成的内容时间,因此警告。
解决此问题的一种方法是不在服务器上呈现使用 useLayoutEffect
的组件。
您可以通过检查是否定义了 window
对象来做到这一点。当它被定义时,这意味着你的代码在客户端上是 运行,只有这样你才应该渲染你的 canvas
组件。
@juliomalves 上面的评论就是答案。谢谢你。我一直在寻找错误的地方。
这是更新后的代码,分为一个页面和一个动态加载的组件(包含一些新内容以提高可见性)。
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;
`;
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>
)
}