Skip to content

리뷰모달/후기 상한선 유효성검사/하이드레이션에러수정 #220

@part3-5

Description

@part3-5

🪐 작업 내용

  • theme-provider.tsx
  • ReviewInput.tsx

📝 간단하게 설명해주세요

하이드레이션 에러 고치기 위해서
관련된 파일 theme-provider.tsx 수정했습니다.

경고 메시지

Hydration` failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used
A server/client branch if (typeof window !== 'undefined'). - Variable input such as Date.now() or Math.random() which changes each time it's called. - Date formatting in a user's locale which doesn't match the server. - External changing data without sending a snapshot of it along with the HTML. - Invalid HTML tag nesting. It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
See more info here: https://nextjs.org/docs/messages/react-hydration-error

  • className="dark"
  • style={{color-scheme:"dark"}}

경고 메시지를 보면 하이드레이션 에러의 주요 원인은 서버와 클라이언트 간의 HTML 불일치입니다.
현재 테마 프로바이더 코드를 다음과 같이 수정하는 것이 좋겠습니다:

"use client";

import { ThemeProvider } from "next-themes";
import { useEffect, useState } from "react";

interface DarkThemeProviderProps {
  children: React.ReactNode;
}

export default function DarkThemeProvider({
  children,
}: DarkThemeProviderProps) {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    return <>{children}</>;
  }

  return (
    <ThemeProvider attribute="class" defaultTheme="light" enableSystem={false}>
      {children}
    </ThemeProvider>
  );
}

주요 변경 사항:

  1. mounted 상태를 추가하여 클라이언트 측 렌더링 시에만 ThemeProvider가 작동하도록 함
  2. 마운트되기 전에는 children을 그대로 렌더링
  3. defaultTheme="light" 추가 (초기 테마를 라이트 모드로 설정)
  4. enableSystem={false} 추가 (시스템 테마 설정 비활성화)

이렇게 하면 서버 사이드 렌더링 시 초기 상태 불일치 문제를 해결할 수 있습니다.
클라이언트 측에서만 테마 변경 로직이 작동하게 됩니다.

주의: 만약 시스템 테마를 사용하고 싶다면 enableSystem={true}로 설정할 수 있지만,
이 경우 더 복잡한 하이드레이션 처리가 필요할 수 있습니다.

✨ To-do

  • [ ]
  • [ ]

📸 참고 사진

이전코드

// theme-provider.tsx
"use client";

import { ThemeProvider } from "next-themes";

interface DarkThemeProviderProps {
 children: React.ReactNode;
}

export default function DarkThemeProvider({
 children,
}: DarkThemeProviderProps) {
 return (
   <>
     <ThemeProvider attribute="class">{children}</ThemeProvider>
   </>
 );
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions