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

React中如何选择HTML元素?基于localStorage实现明暗主题切换

在React中实现基于localStorage的明暗主题切换

核心思路

不用组件内Ref,直接操作index.html里的根DOM元素(比如<html>或<body>),结合localStorage存储用户主题偏好,再用React的状态钩子同步主题状态。

具体实现步骤

1. 初始化主题状态

在根组件(比如App.js)里,从localStorage读取保存的主题,没有的话用默认值(比如light):

import { useState, useEffect } from 'react';

function App() {
  // 从localStorage获取保存的主题,默认浅色
  const [theme, setTheme] = useState(localStorage.getItem('theme') || 'light');

2. 同步主题到DOM元素

用useEffect钩子,每当theme变化时,修改根元素的类名,同时更新localStorage:

useEffect(() => {
    // 获取html根元素
    const root = document.documentElement;
    // 先移除之前的主题类,避免冲突
    root.classList.remove('light', 'dark');
    // 添加当前主题类
    root.classList.add(theme);
    // 把主题偏好存到localStorage
    localStorage.setItem('theme', theme);
  }, [theme]);

3. 实现主题切换按钮

添加一个切换按钮,点击时切换theme状态:

const toggleTheme = () => {
    setTheme(prev => prev === 'light' ? 'dark' : 'light');
  };

  return (
    <div className="app">
      <button onClick={toggleTheme}>
        切换到{theme === 'light' ? '深色' : '浅色'}主题
      </button>
      {/* 其他组件内容 */}
    </div>
  );
}

export default App;

4. 编写CSS主题样式

在全局CSS文件(比如index.css)里定义两种主题的样式,用CSS变量统一管理:

/* 浅色主题默认变量 */
:root {
  --bg-color: #ffffff;
  --text-color: #333333;
}

/* 深色主题变量覆盖 */
.dark {
  --bg-color: #1a1a1a;
  --text-color: #f0f0f0;
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
  transition: background-color 0.3s, color 0.3s;
}

为什么不用组件Ref?

因为index.html里的根元素(<html>)属于全局DOM,不在React组件的DOM树范围内,直接用document.documentElement获取更直接,Ref主要用于操作组件内部渲染的DOM元素。

额外优化:避免页面闪屏

如果希望页面一加载就应用保存的主题,避免短暂的默认主题闪屏,可以在public/index.html里添加一段脚本,在React加载前就设置主题:

<!-- public/index.html -->
<script>
  // 页面加载时立即读取并应用主题
  const savedTheme = localStorage.getItem('theme') || 'light';
  document.documentElement.classList.add(savedTheme);
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:07:44