Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

heyday2024 님의 블로그

버전 관련 트러블 슈팅 본문

카테고리 없음

버전 관련 트러블 슈팅

heyday2024 2024. 12. 11. 22:14

문제

  • 상황:
    // NewProductList.tsx
    
    {/* @ts-expect-error Async Server Component */}
    const NewProductList = async () => {
      const res = await fetch("http://localhost:4001/products", {
        cache: "no-store",
      });
      const data = await res.json();
      const newData = data.filter((p) => p.isNew);
    
      return (
        <div className="flex gap-2 overflow-auto">
          {newData.map((product) => (
            <div className="flex" key={product.id}>
              <img
                className="rounded-sm object-scale-down"
                width={80}
                src={product.images}
                alt={product.title}
              />
              <div className="flex flex-col justify-between">
                <h2 className="text-md font-medium">{product.title}</h2>
                <p className="mt-4 font-thin">{product.price.amount}$</p>
              </div>
            </div>
          ))}
        </div>
      );
    };
    
    export default NewProductList;
    

     
    • NewProductList 컴포넌트를 Server Component로 구현하면서 async 키워드를 사용하여 데이터를 비동기로 가져옴. NewProducList를 page.tsx에서 import 해와서 return에 넣어주었으나. 이 NewProducList에 빨간 줄이 생김(오류 발생....)
    • yarn dev 개발 모드에서는 오류를 무시하고 페이지에서는 렌더링되었으나, 의도한대로 렌더링되지 않았음. 그래서 yarn build && yarn start를 터미널에 입력해서 확인해보니 아래와 같은 에러 확인이 가능했음. 
  • 에러 내용:
    • NewProductList가 JSX 요소로 사용할 수 없다는 에러(TS2786)가 발생:
      'NewProductList' cannot be used as a JSX component.
      Its type '() => Promise<JSX.Element>' is not a valid JSX element type.
  • 문제 원인
    1. 비동기 컴포넌트의 타입 제한:
      • React는 JSX 구성 요소로 사용 가능한 타입을 ReactNode로 제한함.
      • async 함수는 항상 Promise<JSX.Element>를 반환하므로, 이는 ReactNode와 호환되지 않아 TypeScript에서 타입 에러가 발생.
    2. TypeScript 및 React 타입 버전 문제:
      • TypeScript 5.1.3 이상과 @types/react 18.2.8 이상 버전에서는 비동기 컴포넌트 사용을 공식적으로 지원.
      • 기존 버전에서는 이러한 기능이 제대로 지원되지 않거나, 비동기 컴포넌트가 JSX 구성 요소로 사용될 때 타입 검사를 통과하지 못함.

해결 과정

  1. 코드 수정 시도:
    • 비동기 컴포넌트의 타입 제한 오류를 맞이했기에 나의 코드 구조와 비동기 작업을 처리하는 코드 부분을 위주로 점검하며 문제를 해결하고자 했으나, 결국 원인을 찾지 못하고 동일한 에러 발생.
    • 또한 강의에서 제공한 코드 스니펫과 내가 작성한 코드와 다른 부분이 없어서 코드를 잘못 짠 것이 원인은 아니라고 생각함.
  2. 문제 본질적인 원인 다시 탐색 시도:
    • 튜터님의 도움과 에러 메시지를 바탕으로 StackOverflow에서 유사 사례를 확인.
    • 문제는 TypeScript 버전과 @types/react 버전이 Next.js의 Server Component 타입 처리 요구사항과 일치하지 않는 데서 비롯된 것으로 판단.
  3. 버전 점검 및 최신화:
    • TypeScript가 최소 5.1.3 이상인지, @types/react가 최소 18.2.8 이상인지 확인:
      • 기존 프로젝트의 typescript와 @types/react는 각각 ^5와 ^18로 설정되어 있었음.
      • 5버전 중 최신, 18 버전 중 최신이라지만 이렇게 명확하지 않을 때에는 최신버전을 다시 그냥 설치해버리는 것도 좋다고 판단.
    • 최신 버전 설치 명령어 실행:
      npm install typescript@latest @types/react@latest
      
      - 혹은 yarn으로 설치 
  4. 검증:
    • 설치 후 yarn build 및 yarn start 명령 실행함. 오류 메세지 사라지고, 빌드 성공함. 또한 내가 의도한 대로 정상 동작되었음을 확인함.

문제의 원인 다시 정리

  1. TypeScript와 React 타입의 불일치:
    • 최신 Next.js에서는 Server Component를 비동기 함수로 정의할 때, 특정 타입 정의가 필요.
    • 구형 @types/react에서는 async 함수가 반환하는 Promise<JSX.Element>를 허용하지 않아 발생한 문제.
  2. 개발 모드와 프로덕션 모드의 차이:
    • 개발 모드(yarn dev):
      • 타입 체크가 비교적 느슨하게 작동하며, 비동기 Server Component도 런타임에서 처리.
    • 프로덕션 모드(yarn build):
      • 엄격한 타입 검사가 이루어져 비동기 함수로 인한 타입 불일치가 에러로 처리됨.

최신 버전 설치로 해결된 이유

  1. TypeScript 5.1.3 이상:
    • Server Component의 비동기 타입 처리를 위한 개선 사항이 포함.
  2. @types/react 18.2.8 이상:
    • React.FC와 같은 타입이 async Server Component를 적절히 처리하도록 업데이트.

최종적으로 에러없이 suspense까지 잘 이용함!

에러없는 page.tsx의 모습


느낀점

  • 작성한 코드에 문제가 없어 보이는데도 에러가 발생할 때는 당황하지 말고, 해당 오류가 버전과 관련이 있는지 차분히 확인해보는 자세가 필요하다는 것을 배웠다. 버전마다 새롭게 제공되는 기능과 더 이상 지원되지 않는 기능을 확인하는 습관이 정말 중요하다는 점도 깨달았다.
  • 또한, 팀원들과 개발 환경을 공유하는 과정에서 원활한 협업을 위해 사용할 프레임워크나 라이브러리의 버전을 미리 정하는 것이 필요하다. 평소에 버전별 변경 사항과 요구사항을 주기적으로 검토하는 습관을 들인다면, 팀원들과 환경을 구성할 때 이러한 정보가 큰 도움이 될 것이라고 생각한다.