react实现主题切换
实现 React 主题切换的常见方法
使用 CSS 变量和状态管理
通过 React 的状态管理(如 useState 或 Context API)结合 CSS 变量实现主题切换。CSS 变量可以在根元素(:root)中定义,通过 JavaScript 动态修改。
import React, { useState } from 'react';
function App() {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light';
setTheme(newTheme);
document.documentElement.setAttribute('data-theme', newTheme);
};
return (
<div className="app">
<button onClick={toggleTheme}>Toggle Theme</button>
<h1>Current Theme: {theme}</h1>
</div>
);
}
export default App;
在 CSS 中定义主题变量:
:root {
--primary-color: #ffffff;
--secondary-color: #000000;
}
[data-theme="dark"] {
--primary-color: #000000;
--secondary-color: #ffffff;
}
body {
background-color: var(--primary-color);
color: var(--secondary-color);
}
使用 Context API 管理主题状态
对于复杂应用,可以通过 Context API 全局管理主题状态,避免 props 层层传递。

import React, { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
export const useTheme = () => useContext(ThemeContext);
在组件中使用:
function ThemedButton() {
const { theme, toggleTheme } = useTheme();
return (
<button onClick={toggleTheme}>
Current Theme: {theme}
</button>
);
}
使用第三方库(如 styled-components)
styled-components 支持主题切换功能,通过 ThemeProvider 传递主题对象。

import styled, { ThemeProvider } from 'styled-components';
const lightTheme = {
background: '#ffffff',
text: '#000000',
};
const darkTheme = {
background: '#000000',
text: '#ffffff',
};
const StyledApp = styled.div`
background: ${props => props.theme.background};
color: ${props => props.theme.text};
`;
function App() {
const [theme, setTheme] = useState(lightTheme);
const toggleTheme = () => {
setTheme(theme === lightTheme ? darkTheme : lightTheme);
};
return (
<ThemeProvider theme={theme}>
<StyledApp>
<button onClick={toggleTheme}>Toggle Theme</button>
</StyledApp>
</ThemeProvider>
);
}
动态加载主题样式文件
通过动态加载不同的 CSS 文件实现主题切换,适合主题样式较复杂的场景。
function loadTheme(themeName) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = `${themeName}.css`;
document.head.appendChild(link);
}
function App() {
const [theme, setTheme] = useState('light');
const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light';
setTheme(newTheme);
loadTheme(newTheme);
};
return (
<div>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
}
结合 localStorage 持久化主题
将用户选择的主题保存到 localStorage,实现刷新后主题不丢失。
function App() {
const [theme, setTheme] = useState(
localStorage.getItem('theme') || 'light'
);
const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light';
setTheme(newTheme);
localStorage.setItem('theme', newTheme);
document.documentElement.setAttribute('data-theme', newTheme);
};
return (
<div>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
}
注意事项
- 性能优化:避免频繁的主题切换导致重渲染,尤其是大型应用。
- 默认主题:在
useEffect中初始化主题,确保与localStorage同步。 - 无障碍性:确保主题切换不影响屏幕阅读器等辅助工具的使用。
以上方法可根据项目需求灵活选择或组合使用。






