카테고리 없음

TypeScript Project Trouble Shooting

zayn 2024. 12. 19. 09:02

 

1. Hydration Error

이유:

  • React의 Hydration 과정에서 서버와 클라이언트의 렌더링 결과가 일치하지 않을 때 발생.
  • 주요 원인:
    1. 서버에서 생성된 HTML과 클라이언트에서 생성된 DOM이 다름.
    2. 클라이언트에서 동적 데이터가 렌더링 결과를 변경.
    3. useEffect, useState와 같은 클라이언트 전용 로직이 서버와 클라이언트의 초기 결과를 다르게 만듦.

해결 방안:

  1. 조건부 렌더링에 주의:
    • 클라이언트 전용 코드(window, document)는 서버 렌더링에서 동작하지 않으므로 useEffect 안에서 처리.
    • 예:
      import { useEffect, useState } from "react";
      
      function ExampleComponent() {
        const [isClient, setIsClient] = useState(false);
      
        useEffect(() => {
          setIsClient(true);
        }, []);
      
        if (!isClient) return null;
      
        return <div>클라이언트에서만 렌더링되는 컴포넌트</div>;
      }
      
  2. 동적 데이터 처리:
    • 초기값을 서버와 동일하게 설정해 Hydration 불일치를 방지.
    • 예:
      const [value, setValue] = useState(() => serverValue || "");
      
  3. key 속성 활용:
    • 상태 변화에 따라 고유한 key를 할당하여 컴포넌트를 강제로 재생성.

2. next-themes 라이브러리 관련 에러

이유:

  • Next.js에서 next-themes를 사용할 때 서버-클라이언트 동기화 문제로 인해 테마 변경이 올바르게 작동하지 않을 수 있음.
  • 주요 원인:
    • 초기 theme 값이 클라이언트에서 렌더링되기 전에 undefined로 설정.
    • ThemeProvider가 올바르게 설정되지 않음.

해결 방안:

  1. 초기 테마 설정:
    • defaultTheme를 system 또는 원하는 값으로 설정.
    import { ThemeProvider } from "next-themes";
    
    function App({ children }: { children: React.ReactNode }) {
      return (
        <ThemeProvider attribute="class" defaultTheme="light">
          {children}
        </ThemeProvider>
      );
    }
    
  2. useEffect로 초기 렌더링 보정:
    • 클라이언트에서만 테마가 동작하도록 초기 렌더링 시점을 명확히 조정.
    import { useTheme } from "next-themes";
    import { useEffect, useState } from "react";
    
    function DarkModeToggle() {
      const { theme, setTheme } = useTheme();
      const [mounted, setMounted] = useState(false);
    
      useEffect(() => setMounted(true), []);
    
      if (!mounted) return null;
    
      return <button onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>Toggle</button>;
    }
    
  3. 필요한 Tailwind 설정 확인:
    • tailwind.config.js에서 다크 모드 속성 설정 확인:
      module.exports = {
        darkMode: "class",
      };
      

3. 불필요한 재렌더링 문제

이유:

  • React 컴포넌트가 불필요하게 다시 렌더링되는 경우:
    1. 부모 컴포넌트의 상태나 props가 자식 컴포넌트에 영향을 미침.
    2. 무분별한 익명 함수(onClick={() => ...}) 사용.
    3. Context API를 과도하게 사용하여 상태 변경이 전파됨.

해결 방안:

  1. React.memo 활용:
    • props 변경이 없는 경우 컴포넌트를 재렌더링하지 않도록 설정.
    import React from "react";
    
    const ChildComponent = React.memo(({ value }: { value: string }) => {
      console.log("렌더링!");
      return <div>{value}</div>;
    });
    
  2. useCallback 사용:
    • 함수 재생성을 방지해 자식 컴포넌트의 재렌더링을 최소화.
    const handleClick = useCallback(() => {
      console.log("클릭!");
    }, []);
    
  3. Context 분리:
    • Context 범위를 좁혀 렌더링 영향을 줄임.

4. vercel.json 설정

이유:

  • Vercel에서 빌드 설정, 리디렉션, API 처리 등 잘못된 설정으로 빌드가 실패하거나 예상치 못한 동작 발생.

해결 방안:

  1. 리디렉션 설정:
    • 정적 페이지와 API 경로가 충돌하지 않도록 설정.
    {
      "redirects": [
        { "source": "/old-path", "destination": "/new-path", "permanent": true }
      ]
    }
    
  2. 서버 함수 제한:
    • API 경로가 너무 많을 경우 ignoreBuildErrors 옵션을 활성화하여 빌드 완료 보장.

5. Next.js와 Yarn 충돌

이유:

  • Next.js 프로젝트에서 Yarn 버전 또는 설치된 패키지 충돌로 인해 의존성 문제가 발생.

해결 방안:

  1. Yarn 버전 확인:
    • 최신 버전(1.x 또는 3.x)을 사용하는지 확인.
  2. yarn --version
  3. node_modules 초기화:
  4. rm -rf node_modules && yarn install
  5. 패키지 충돌 확인:
    • yarn why 명령어를 사용해 충돌하는 패키지 확인:
      yarn why next
      
  6. 의존성 강제 설치:
  7. yarn add next@latest react@latest react-dom@latest

이제야 리액트가 좀 익숙해졌는데 타임스크립트로 넘어오면서 다시 새롭게 어렵고 적응안되는것 말고는 조금 할 만 해 졌고 tailwind 본인거 공유해주신 현희행님 덕에 이쁘고 이쁜 UI 만든거 같아서 감사할 뿐이다. 히히