if(window){...} // window is not definde 에러발생
if(typeof window !== undefined) {...} // 정의되지않은 window의 타입이기떄문에 undefied가 발생 -> 에러가 발생하지 않습니다.
간단하게 이러한 방법으로 window객체가 있는지 체크하는 방법이 있습니다.
useEffect(()=>{
// 안에서 window 객체를 사용
},[])
useEffect는 DOM형성 후에 실행이 되는 hook입니다. 고로 브라우저가아닌 서버에서 window를 체크를 하지 않는 다는 것이죠. react를 사용하면서 가장 편하게 사용할 수 있는 방법이 아닐까 싶습니다.
import dynamic from 'next/dynamic'
const ComponentsWithNoSSR = dynamic<{props:type;}>( // typescript에서 props를 전달할때 interface를 정의해줍니다.
() => import('./components/Component'), // Component로 사용할 항목을 import합니다.
{ ssr: false } // ssr옵션을 false로 설정해줍니다.
);
const App = () => {
return(
<div>
<Components/> // 해당 컴포넌트는 SSR로 불러올 수 있습니다.
<ComponentsWithNoSSR/> // 해당 컴포넌트는 ssr:false이기 때문에 서버사이드 렌더를 하지않습니다.
</div>
)
};
next.js에서 제공하는 dynamic이라는 함수로 ssr옵션을 꺼줄 수 있으며, 이로 인해 window를 사용하는 컴포넌트에서 에러가 나는 것을 막을 수 있습니다.
이번에 프로젝트를 하는 도중 next.js를 사용하고 build를 하는데 window is not defined라는 에러때문에 다양한 방법을 사용했지만, 외부 라이브러리를 사용하거나 특정상황에서 window객체를 useEffect에 넣지 못하는 상황이 있었습니다. 그럴때 아예 그 Components를 ssr로 불러오지 않는다면 해결되는 것을 알았고, 마침 next.js에서 제공하는 dynamic이라는 모듈로 해결을 볼 수 있었습니다. 단순히 ssr옵션을 부여하는 것이아닌, loading도중 어떠한 컴포넌트를 보여줄지도 설정할 수 있으며, build할때 용량도 줄일 수 있는 장점이 있었습니다. 작동원리나 용량이 줄어드는 이유는 다음 포스팅때 다뤄보도록 하겠습니다.
"use client" 를 코드 제일 위에 적어도 됩니다.
https://nextjs.org/docs/app/building-your-application/rendering/client-components
dynamic 함수를 이용하여 ssr 옵션이 꺼지게 된다면, getServerSideProps 나 getStaticProps를 사용할 수 없는건가요?