使用ChakraUI时生产环境出现Div位置异常、重复Home div问题
问题原因
这个是典型的服务端渲染(SSG/SSR)与客户端Hydration不匹配导致的问题,你用的应该是Gatsby这类静态站点生成框架,开发模式下是客户端实时渲染所以不会出问题,生产构建时先生成静态HTML,再到客户端做Hydration,两者结构不一致就会出现DOM结构错乱、重复节点的问题:
- 你用到的
useBreakpointValue、colorMode都是依赖客户端运行环境的属性,服务端构建时无法获取客户端实际屏幕尺寸、本地存储的颜色模式值,导致服务端生成的HTML结构和客户端首次Hydration生成的结构不匹配 - React 18的Hydration容错机制会尝试修复结构不匹配的问题,修复过程中就会生成多余的DOM节点、甚至出现节点错位的情况,你切换颜色模式时会触发全局组件重渲染,错乱的结构被新渲染的结构覆盖,所以就恢复正常了
- 额外注意你
bgGradient属性值末尾多写了一个分号,生产构建时Chakra UI的样式解析逻辑比开发模式严格,也可能导致样式属性解析异常,触发结构渲染错误
修复方案
处理Hydration不匹配问题
对依赖客户端环境的组件增加挂载判断,等到客户端Hydration完成后再渲染实际内容,你可以直接在Home组件里加挂载判断逻辑:import { useState, useEffect } from 'react' const Home = () => { const [isMounted, setIsMounted] = useState(false) // 组件挂载后说明Hydration已完成 useEffect(() => setIsMounted(true), []) const big = useBreakpointValue({ base: false, md: true }) // 未挂载时返回空或者骨架屏占位,避免结构不匹配 if (!isMounted) return null return ( <Section id="home" color="white"> {/* 原有Home组件逻辑 */} </Section> ) } export default Home修正样式属性
删除bgGradient属性值末尾的多余分号:bgGradient={ colorMode !== "dark" ? "radial(bgOrange.100, bgOrange.500)" : "" }校验颜色模式配置
如果你用了Chakra UI的Gatsby插件,确认gatsby-config.js里的初始颜色模式配置和客户端默认值一致,避免服务端和客户端初始colorMode值不同:// gatsby-config.js 中Chakra插件配置示例 { resolve: '@chakra-ui/gatsby-plugin', options: { initialColorMode: 'light', ssr: true, }, }
内容的提问来源于stack exchange,提问作者Jimmy Soussan
相关产品推荐
相关产品推荐

