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

如何通过useState与切换按钮切换React应用的CSS文件引入?

在React中切换CSS文件实现主题切换的可行方案

你之前尝试通过条件渲染<link>标签的方法无效,原因是:React将<link>插入DOM后,切换时会新增一个标签而非替换旧的,两个CSS文件会同时生效导致样式叠加,浏览器也不会自动移除已加载的旧CSS。

下面是几种可行的实现方式:

方法一:修改已有link标签的href属性

先在public/index.html中添加一个带ID的固定link标签:

<link id="theme-link" rel="stylesheet" href="/App.css" />

然后在React组件中通过DOM操作切换href:

import { useState } from 'react';

function App() {
  const [useLightTheme, setUseLightTheme] = useState(true);

  const toggleTheme = () => {
    const themeLink = document.getElementById('theme-link');
    if (themeLink) {
      themeLink.href = useLightTheme ? '/App2.css' : '/App.css';
      setUseLightTheme(!useLightTheme);
    }
  };

  return (
    <>
      <h1>Hello, World!</h1>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </>
  );
}

export default App;

方法二:使用CSS变量(推荐)

无需切换整个CSS文件,通过修改根元素类名切换CSS变量值,更灵活且无文件加载问题:

/* 定义主题变量 */
:root.light {
  --bg: #fff;
  --text: #333;
}

:root.dark {
  --bg: #1a1a1a;
  --text: #fff;
}

/* 使用变量 */
body {
  background-color: var(--bg);
  color: var(--text);
  transition: background-color 0.3s, color 0.3s;
}

组件中切换类名:

import { useState, useEffect } from 'react';

function App() {
  const [isDark, setIsDark] = useState(false);

  useEffect(() => {
    const root = document.documentElement;
    if (isDark) {
      root.classList.add('dark');
      root.classList.remove('light');
    } else {
      root.classList.add('light');
      root.classList.remove('dark');
    }
  }, [isDark]);

  const toggleTheme = () => setIsDark(!isDark);

  return (
    <>
      <h1>Hello, World!</h1>
      <button onClick={toggleTheme}>Toggle Dark/Light</button>
    </>
  );
}

export default App;

方法三:动态添加/移除link标签

如果一定要用两个独立CSS文件,可以在切换时移除旧标签并添加新标签:

import { useState, useEffect } from 'react';

function App() {
  const [useStyle1, setUseStyle1] = useState(true);

  useEffect(() => {
    // 移除已存在的主题标签
    const oldLink = document.querySelector('link[data-theme]');
    if (oldLink) oldLink.remove();

    // 创建新标签
    const newLink = document.createElement('link');
    newLink.rel = 'stylesheet';
    newLink.href = useStyle1 ? './App.css' : './App2.css';
    newLink.setAttribute('data-theme', 'active');
    document.head.appendChild(newLink);

    // 组件卸载时清理
    return () => newLink.remove();
  }, [useStyle1]);

  const toggleStyle = () => setUseStyle1(!useStyle1);

  return (
    <>
      <h1>Hello, World!</h1>
      <button onClick={toggleStyle}>Toggle Style</button>
    </>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:28:28