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

React暗黑模式开发:useState仅能两次设置样式对象值的问题

React暗黑模式切换失效问题解决

你的问题出在直接比较对象引用上。JavaScript中,即使两个对象内容完全一致,它们的引用也是独立的(除非是同一个对象)。你用appear === whitem这种方式判断状态,再加上React对对象类型state的浅比较机制,会导致状态更新异常,出现只能切换两次的情况。

修复方案

不要把样式对象直接存在state里,改用布尔值标记当前是否为暗黑模式,再根据这个值动态选择样式:

import React, { useState } from 'react'

export const About = () => {
  const whitem = {
    color: "black",
    backgroundColor : "white"
  }
  const darkm = {
    color: "white",
    backgroundColor : "black"
  }

  // 用布尔值跟踪暗黑模式状态
  const [isDarkMode, setIsDarkMode] = useState(false)
  // 根据当前模式推导按钮文本和样式
  const btntext = isDarkMode ? 'Enable white mode' : 'Enable dark mode'
  const currentStyle = isDarkMode ? darkm : whitem

  const btn_handler = () => {
    console.log("button clicked")
    // 直接切换布尔值完成模式切换
    setIsDarkMode(!isDarkMode)
  }

  return (
    <div className='container my-4' style={currentStyle}>
      <h2 style={currentStyle}>Heading</h2>
      <p style={currentStyle}>
        Lorem ipsum dolor sit amet consectetur, adipisicing elit. In, et. At officiis aliquam quidem, nihil est consectetur quas perferendis a quibusdam porro ex nesciun
      </p>
      <button
        onClick={btn_handler}
        type='button'
        className='btn btn-dark my-4'
      >
        {btntext}
      </button>
    </div>
  )
}

原代码失效原因

  1. 第一次点击按钮,appear被设置为darkm(新对象引用),组件正常重新渲染。
  2. 第二次点击,appear被设置回whitem(和初始状态相同的引用),React浅比较后认为状态无变化,虽btntext更新会触发渲染,但appear的引用一致性会干扰后续判断逻辑。
  3. 后续点击时,appear === whitem的引用比较会出现异常,导致无法正确触发状态切换。

改用布尔值跟踪模式状态,不仅逻辑更简洁,还能彻底避免对象引用比较带来的问题,同时减少冗余的state变量。

内容的提问来源于stack exchange,提问作者Ravi Choudhary

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:57:39