본문 바로가기

FrontEnd

Next js - [window is undefined 에러]

"window is undefined"

라는 에러를 next js 프레임워크로 마이그레이션 하면서 처음봤다. 

 

react에서 서버사이드 렌더링(next js 프레임워크)을 할때에

웹 페이지를 렌더링 할때에 초기에는 window나 document 전역객체는 선언되지 않기 때문에

해당 변수를 참조할수 없기 때문에 벌어진 일이다.

 

원인

그러면 중요한 키포인트는 해당 변수를 참조하지 않아도 페이지가 '일단은' 구동하기만 하면

이후에 선언되는 window나 document 변수들이 참조되면서 변수가 제대로 구동하게 하면 되지 않나?

 

그래서 나중에 배포할 때에 웹페이지를 static page로 빌드 하면서 '일단은' 구동하기면 하면 되도록

문제를 일으키는 변수들에 대해서 조건부 렌더링을 걸었다.

 

해결

문제를 일으킨 변수들은 다음과 같이 선언한다.

const [cart, setCart] = useState(typeof window !== "undefined" ? 
	JSON.parse(window.localStorage.getItem('cart')) : null);

중요한 점은 type of window !== "undefined" 

window 전역객체가 참조되지 않을 경우 "undefined"를 반환하기 때문에 위와 같이 설정한다. 

 

아니면

 

let cart = null;
useEffect(() => {
    cart = window.localStorage.getItem('cart'));
},[] )

useEffect() 는 초기 빌드에는 실행되지 않으므로 문제되는 코드를 useEffect() 안으로 넣어버려도 된다.

 

 

 

이후에

static page build 시에는 cart 변수는 null로 설정이 되고 이후 해당 변수에서 문제를 일으키는 부분에서 조건부 렌더링을 해준다. 

<div className={classes.productCart}>
                            {

                                cart === null ?
                                    <Box className={classes.productCartTag}>
                                        <ShoppingCartIcon />
                                        <span > 장바구니가 비어있습니다.</span>
                                    </Box>
                                    :
                                    cart.length !== 0 ?
                                        cart.map((product, index) => {
                                            return <AddToCart
                                                key={index}
                                                image={product.image}
                                                title={product.title}
                                                price={product.price}
                                                quantity={product.quantity}
                                                removeToCart={removeToCart}
                                            />
                                        }) :
                                        <Box className={classes.productCartTag}>
                                            <ShoppingCartIcon />
                                            <span > 장바구니가 비어있습니다.</span>
                                        </Box>

                            }
                        </div>

이렇게 해주면 cart 변수가 null일 경우 조건부로 렌더링이 되어 static 페이지가 깔끔하게 된다. 

 

참고

 

www.sungikchoi.com/blog/window-is-not-available/

'FrontEnd' 카테고리의 다른 글

CSS 애니메이션 & JS 애니메이션  (0) 2021.01.14
CD와 CI  (0) 2021.01.14
모듈 번들러와 트랜스파일러  (0) 2021.01.14
BOM & DOM  (0) 2021.01.13
자바스크립트 엔진이 코드를 실행하는 과정  (0) 2021.01.13