본문 바로가기
프로젝트 기록

[Next.js] next build 시 window is not defined 에러 해결하기

by dygreen 2023. 5. 21.

컴포넌트에서 window 객체를 사용하지 않는 경우

리뷰를 등록하고 수정하는 역할을 하는 <ModalReviewAdd/>라는 컴포넌트에서는 window 객체를 사용하지 않는데

Error occurred prerendering page "/detail/components/ModalReviewAdd". Read more: https://nextjs.org/docs/messages/prerender-error ReferenceError: window is not defined

이런 build 에러가 발생했다.

도저히 어디서 잘못된 건지 감이 잡히지 않아 한참을 헤맸던 것 같다...

 

 

결국 여러 번의 시도 끝에 해결한 코드는 다음과 같다.

import React, {useEffect, useState} from "react"

interface ReviewAddProps {
  currentReview: ReviewItem;
  toggleReviewModal(): void;
  fnAddNewReview(): void;
}

const reviewItemInit: ReviewItem = {
  reviewId: "",
  movieId: "",
  content: ""
}

const ModalReviewAdd = (props: ReviewAddProps) => {
  const [currentReview, setCurrentReview] = useState<ReviewItem>(reviewItemInit)

  useEffect(() => {
    setCurrentReview(props.currentReview)
  },[props.currentReview])

  return props.currentReview ? (
      <div className={detail.addBox}>
        <h2>리뷰 쓰기</h2>
        <div className={detail.addText}>
          <input
            type="text"
            disabled
          />
          <textarea
            placeholder="영화에 대한 솔직한 리뷰를 남겨주세요."
            maxLength={100}
            name="content"
            value={currentReview.content}
          />
        </div>
      </div>
  ): <></>
}

export default ModalReviewAdd

(코드는 최대한 필요한 부분만 남겼다)

 

방법은 렌더링 조건을 추가하는 것 (return props.currentReview ? (<div></div>) : <></>) 이다.

컴포넌트에서 JSX를 return 하기 전에 조건을 주니 해결되었다. (정확한 방식이 맞는지는 모르겠다..😢)

 

부모 컴포넌트에서 넘겨주는 currentReview라는 state에 값이 있을 때만 자식 컴포넌트(<ModalReviewAdd/>)를 렌더링할 수 있게 조건을 주는 것이다. 

조건을 주기 전에는 currentReview 값이 없는 상태로 <ModalReviewAdd/>를 렌더링하게 되는데,

해당 코드에선 textarea 태그의 value 값으로 들어갈 값이 없어서 에러가 난 것 같다.

 

window 객체를 사용하는 경우

에러를 잡기 위해 여러 방면으로 알아보던 중, window 객체를 사용했을 경우 (에러 해결을 위해) 해보면 좋을 방법들을 배워 정리해보고자 한다.

 

1. window 객체의 사용 조건 추가

if (typeof window !== "undefined") {
  // window 객체를 사용하는 코드
}

 

2. 페이지 컴포넌트를 동적으로 불러오도록 수정

import dynamic from "next/dynamic";

const ModalReviewAdd = dynamic(() => import("./ModalReviewAddPath"), { ssr: false });

→ window is not defined 에러는 SSR 중에 클라이언트 전용 window 객체를 사용할 수 없기 때문에 발생하는 것이다.

따라서 해당 컴포넌트를 동적으로 불러와서 문제를 해결할 수 있다.

이렇게 수정하면 Server-Side에서 해당 컴포넌트를 불러오지 않고, Clinet-Side에서 렌더링할 때만 불러와서 window is not defined 오류가 발생하지 않는다.

728x90

댓글