Dark mode 는 하나인 척하는 세 문제: 어떤 모드 활성, 선택 어디 살아남, React 마운트 전 페이지 렌더 어떻게. 셋 다 풀거나 토글이 매 reload 마다 깜빡거려.
세 레이어
- 현재 모드 — light, dark, 또는 'system 따라'.
- Persistence — 사용자 선택이 페이지 reload 살아남아야 (localStorage).
- 초기 렌더 — React 렌더 전에 HTML 이 이미 올바른 theme attribute 가져야 — 안 그러면 페이지가 한 프레임 동안 잘못된 색 깜빡.
Pre-React 스크립트
깜빡 피하려면 index.html 의 inline script 에서 <html> 에 theme attribute 설정 — Vite 번들 로드 전에. localStorage 읽고; prefers-color-scheme 으로 fallback. 이 스크립트가 동기적으로 돌고 페이지가 즉시 올바른 색으로 paint.
React hook
React 안에서 useTheme hook 이 현재 attribute 읽고, setter 노출, localStorage 에 write back. Hook 이 페이지 내 토글 UI 구동. Pre-React 스크립트가 부팅 처리, hook 이 사용자 구동 변경 처리.
'System 따라'
일부 사용자는 OS preference 원함. matchMedia('(prefers-color-scheme: dark)') change 이벤트 listen. 사용자가 명시적 모드 안 골랐으면 (localStorage 항목 없음) 시스템 신호 따라. 모드 고르는 순간 시스템 신호 override.
서버 사이드 기본값에 토글 렌더하고 희망하지 마. SSR (Next.js) 로 옮기면 서버가 사용자 preference 모름. Flash-free 서버 렌더 (쿠키 사용) 출하 또는 hydration 까지 theme-의존 UI 렌더 스킵. SPA 는 이 버그 클래스 전체 피함 — inline 스크립트가 다른 거 전에 돔.