Next.js使用内联样式时渲染异常并抛出style属性不匹配警告
问题根源
- Hydrate 阶段一致性要求:Next.js SSR 生成的 HTML 结构、属性必须和客户端首次 hydrate 渲染的结果完全一致,否则会抛出
Prop did not match类警告,且 React 会优先保留服务端渲染的内容,导致后续状态更新表现异常。 - 代码逻辑存在两处问题触发上述规则:
- 初始状态判断逻辑不一致:服务端运行时
window不存在,isServer初始值为true;客户端运行时window存在,isServer初始值为false,导致首屏 hydrate 时服务端返回的红色样式和客户端渲染的黄色样式不匹配。 - 状态更新未触发重渲染:无依赖
useEffect中设置的isServer值和客户端初始值完全相同,不会触发状态更新,组件不会重新渲染,因此样式一直停留在服务端渲染的红色。
- 初始状态判断逻辑不一致:服务端运行时
解决方案
直接修正代码
调整初始状态赋值,保证服务端与客户端 hydrate 阶段状态一致即可:
import React, { useEffect, useState } from 'react' export default function Index() { // 初始值统一设为true,规避hydrate阶段不一致问题 const [isServer, setIsServer] = useState(true) const style = { color: isServer ? 'red' : 'yellow', } useEffect(() => { // hydrate完成后更新为客户端实际状态,触发重渲染更新样式 setIsServer(typeof window === 'undefined') }, []) return ( <div> <h1 style={style}>Hi I am Danny</h1> </div> ) }
封装通用 Hook(可选)
如果项目多处分发需要区分 SSR/CSR 环境,可封装通用 Hook 简化调用:
// hooks/useIsClient.js import { useState, useEffect } from 'react' export default function useIsClient() { const [isClient, setIsClient] = useState(false) useEffect(() => { setIsClient(true) }, []) return isClient }
调用示例:
const isClient = useIsClient() const style = { color: isClient ? 'yellow' : 'red' }
内容的提问来源于stack exchange,提问作者DannyWang
相关产品推荐
相关产品推荐

