# SSR Hydration 에러 해결 작업 기록 ## 문제 상황 ### 1차 에러: useData is not defined - **위치**: ItemMasterDataManagement.tsx:389 - **원인**: 리팩토링 후 `useData()` → `useItemMaster()` 변경 누락 - **해결**: 함수 호출 변경 ### 2차 에러: Hydration Mismatch ``` Hydration failed because the server rendered HTML didn't match the client ``` - **원인**: Context 파일에서 localStorage를 useState 초기화 시점에 접근 - **영향**: 서버는 초기값 렌더링, 클라이언트는 localStorage 데이터 렌더링 → HTML 불일치 ## 근본 원인 분석 ### ❌ 문제가 되는 패턴 (React SPA) ```typescript const [data, setData] = useState(() => { if (typeof window === 'undefined') return initialData; const saved = localStorage.getItem('key'); return saved ? JSON.parse(saved) : initialData; }); ``` **문제점**: - 서버: `typeof window === 'undefined'` → initialData 반환 - 클라이언트: localStorage 값 반환 - 결과: 서버/클라이언트 HTML 불일치 → Hydration 에러 ### ✅ SSR-Safe 패턴 (Next.js) ```typescript const [data, setData] = useState(initialData); useEffect(() => { try { const saved = localStorage.getItem('key'); if (saved) setData(JSON.parse(saved)); } catch (error) { console.error('Failed to load data:', error); localStorage.removeItem('key'); } }, []); ``` **장점**: - 서버/클라이언트 모두 동일한 초기값으로 렌더링 - useEffect는 클라이언트에서만 실행 - Hydration 후 localStorage 데이터로 업데이트 - 에러 처리로 손상된 데이터 복구 ## 수정 내역 ### AuthContext.tsx - 2개 state: users, currentUser - localStorage 로드를 단일 useEffect로 통합 - 에러 처리 추가 ### ItemMasterContext.tsx - 13개 state 전체 SSR-safe 패턴 적용 - 통합 useEffect로 모든 localStorage 로드 처리 - 버전 관리 유지: - specificationMasters: v1.0 - materialItemNames: v1.1 - 포괄적 에러 처리 및 손상 데이터 정리 ## 예상 부작용 및 완화 ### Flash of Initial Content (FOIC) - **현상**: 초기값 표시 → localStorage 데이터로 전환 - **영향**: 매우 짧은 시간 (보통 눈에 띄지 않음) - **완화**: 필요시 loading state 추가 가능 ### localStorage 데이터 손상 - **대응**: try-catch로 감싸고 손상 시 localStorage 클리어 - **결과**: 기본값으로 재시작하여 앱 정상 동작 유지 ## 테스트 결과 - ✅ Hydration 에러 해결 - ✅ localStorage 정상 로드 - ✅ 서버/클라이언트 렌더링 일치 - ✅ 에러 없이 페이지 로드 ## 향후 고려사항 - 나머지 8개 Context (Facilities, Accounting, HR, etc.)는 실제 사용 시 동일 패턴 적용 필요 - 복잡한 초기 데이터가 있는 경우 서버에서 데이터 pre-fetch 고려 - Critical한 초기 데이터는 서버 컴포넌트에서 직접 전달하는 방식 검토 가능 ## 참고 문서 - Next.js SSR/Hydration: https://nextjs.org/docs/messages/react-hydration-error - React useEffect: https://react.dev/reference/react/useEffect