Skip to content

Commit f96f3ba

Browse files
committed
fix: 修复主题切换回白天模式不生效
1 parent 8561cc7 commit f96f3ba

1 file changed

Lines changed: 26 additions & 21 deletions

File tree

src/components/ThemeToggle.tsx

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
1-
import { useEffect, useState } from 'react';
1+
import { useCallback, useSyncExternalStore } from 'react';
2+
3+
function getIsDark() {
4+
return document.documentElement.classList.contains('dark');
5+
}
6+
7+
function subscribe(callback: () => void) {
8+
const observer = new MutationObserver(callback);
9+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
10+
return () => observer.disconnect();
11+
}
12+
13+
function applyTheme(dark: boolean) {
14+
if (dark) {
15+
document.documentElement.classList.add('dark');
16+
} else {
17+
document.documentElement.classList.remove('dark');
18+
}
19+
localStorage.setItem('theme', dark ? 'dark' : 'light');
20+
const meta = document.querySelector('meta[name="theme-color"]');
21+
if (meta) meta.setAttribute('content', dark ? '#111110' : '#fafaf9');
22+
}
223

324
export function ThemeToggle() {
4-
const [isDark, setIsDark] = useState(false);
25+
const isDark = useSyncExternalStore(subscribe, getIsDark);
526

6-
useEffect(() => {
7-
const stored = localStorage.getItem('theme');
8-
if (stored) {
9-
setIsDark(stored === 'dark');
10-
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
11-
setIsDark(true);
12-
}
27+
const toggle = useCallback(() => {
28+
applyTheme(!getIsDark());
1329
}, []);
1430

15-
useEffect(() => {
16-
if (isDark) {
17-
document.documentElement.classList.add('dark');
18-
} else {
19-
document.documentElement.classList.remove('dark');
20-
}
21-
localStorage.setItem('theme', isDark ? 'dark' : 'light');
22-
const meta = document.querySelector('meta[name="theme-color"]');
23-
if (meta) meta.setAttribute('content', isDark ? '#111110' : '#fafaf9');
24-
}, [isDark]);
25-
2631
return (
2732
<button
28-
onClick={() => setIsDark(!isDark)}
33+
onClick={toggle}
2934
className="flex items-center justify-center w-7 h-7 rounded-lg border border-edge bg-base text-dim transition-all duration-150 hover:border-edge-hover hover:text-body hover:bg-surface"
3035
aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
3136
>

0 commit comments

Comments
 (0)