监听 prefers-color-scheme,跟随系统亮暗色
./web 子入口导出:import {useSystemTheme} from '@skyroc/hooks/web'。RN 端不可用。function useSystemTheme(): {
isDarkMode: boolean;
isLightMode: boolean;
themeName: 'dark' | 'light';
};导出的 ThemeName 类型即 'dark' | 'light'。
import { useSystemTheme } from '@skyroc/hooks/web';
const ThemeIndicator = () => {
const { themeName } = useSystemTheme();
return <span>当前系统主题:{themeName}</span>;
};初始值用惰性 initializer,服务端直接返回 false:
const [isDarkMode, setIsDarkMode] = useState(() => {
if (typeof window === 'undefined') return false;
return window.matchMedia('(prefers-color-scheme: dark)').matches;
});useEffect 里会再 setIsDarkMode(mediaQuery.matches) 同步一次真实值,所以 hydration 后即使首屏渲染成 light 也会立刻纠正。服务端渲染的首帧一律是 light,需要避免闪烁就在 <head> 里内联一段脚本提前打 class。
监听通过 mediaQuery.addEventListener('change', ...) 注册,卸载时 removeEventListener。
这个 hook 只反映系统偏好,不代表应用当前主题——应用可能被用户显式锁定为亮色或暗色。后台的完整主题状态(含「跟随系统 / 强制亮 / 强制暗」三态、持久化、CSS 变量注入)在 @skyroc/web-admin-theme,它内部消费的正是这个 hook。
业务代码要读当前主题,用 web-admin-theme 的 hooks,不要直接用 useSystemTheme。
Last updated on