You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js使用内联样式时渲染异常并抛出style属性不匹配警告

问题根源
  1. Hydrate 阶段一致性要求:Next.js SSR 生成的 HTML 结构、属性必须和客户端首次 hydrate 渲染的结果完全一致,否则会抛出 Prop did not match 类警告,且 React 会优先保留服务端渲染的内容,导致后续状态更新表现异常。
  2. 代码逻辑存在两处问题触发上述规则:
    • 初始状态判断逻辑不一致:服务端运行时 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 19:54:03