λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ’‘ issue

Next.js window is not defined 원인 및 해결방법

by HandHand 2022. 6. 17.

πŸ“Œ μƒˆλ‘œκ³ μΉ¨ μ‹œ 였λ₯˜ νŽ˜μ΄μ§€κ°€ λ– μš”!

ν˜„μž¬ νšŒμ‚¬μ—μ„œ Next.js λ₯Ό μ΄μš©ν•œ ν”„λ‘œμ νŠΈλ₯Ό μ§„ν–‰ν•˜κ³  μžˆλŠ”λ°

νŠΉμ • νŽ˜μ΄μ§€μ—μ„œ μƒˆλ‘œκ³ μΉ¨μ„ ν•˜κ±°λ‚˜ URL 을 톡해 직접 접근을 μ‹œλ„ν•  경우

μ—λŸ¬κ°€ λ°œμƒν•˜λ©° μ—λŸ¬ νŽ˜μ΄μ§€λ‘œ λ¦¬λ‹€μ΄λ ‰μ…˜λ˜λŠ” μ΄μŠˆκ°€ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

πŸ“Œ 였λ₯˜ λ°œμƒ 원인은?

ν•΄λ‹Ή νŽ˜μ΄μ§€μ—μ„œλŠ” custom hook 을 μ‚¬μš©ν•˜κ³  μžˆμ—ˆλŠ”λ° μ—¬κΈ°μ„œ λ¬Έμ œκ°€ λ°œμƒν•œ κ²ƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

πŸ’‘ λ¬Έμ œκ°€ 된 custom hook

λ‹€μŒμ€ μ΄λ²ˆμ— 문제λ₯Ό μΌμœΌν‚¨ 주범인 custom hook 의 κ°„λ‹¨ν•œ μ˜ˆμ‹œμž…λ‹ˆλ‹€.

export default const customHook = () => {
    const [flag, setFlag] = useState(Number(localStorage.getItem(countKey) || '0'))

    // λͺ‡κ°€μ§€ μž‘μ—…λ“€ ...

    return [flag, setFlag]
}

Next.js μ—μ„œ SSR 을 ν• λ•Œ νŽ˜μ΄μ§€λ₯Ό 처음 λ Œλ”λ§ν•˜λŠ” κ³Όμ •μ—μ„œλŠ”

window λ‚˜ document μ „μ—­ 객체가 μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μœ„μ˜ 경우 window 객체의 둜컬 μŠ€ν† λ¦¬μ§€μ— μ ‘κ·Όν•˜κ³ μžˆκΈ° λ•Œλ¬Έμ— undefined μ°Έμ‘° 였λ₯˜κ°€ λ°œμƒν•˜κ²Œλ©λ‹ˆλ‹€.

 

πŸ“Œ window μ°Έμ‘° 였λ₯˜ ν•΄κ²°ν•˜κΈ°

1️⃣ typeof μ—°μ‚°μž

첫번째 방법은 window 객체가 μ‘΄μž¬ν•˜λŠ”μ§€ νŒλ‹¨ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

μœ„ μ˜ˆμ œμ— 이 방법을 μ μš©ν•˜λ©΄ λ‹€μŒκ³Ό 같이 μ½”λ“œλ₯Ό λ°”κΏ€ 수 μžˆμŠ΅λ‹ˆλ‹€.

const [flag, setFlag] = useState(
    typeof window !== 'undefined'
      ? Number(localStorage.getItem(resurrectionCountKey)) || 0
      : 0,
)

2️⃣ useEffect Hook

κ·Έ λ‹€μŒ 방법은 useEffect λ₯Ό μ΄μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

useEffect λŠ” λ Œλ”λ§ 이후에 호좜되기 λ•Œλ¬Έμ— 였직 ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œμ—μ„œλ§Œ λ™μž‘ν•¨μ„ 보μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ μ•ˆμ „ν•˜κ²Œ 전역객체에 접근이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

useEffect(() => {
    /** μ—¬κΈ°μ„œ window ν˜Ήμ€ document 객체에 μ ‘κ·Όν•˜κΈ° */
}, [])

3️⃣ next/dynamic

Next.js λŠ” ES2020 의 dynamic import λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€.

ssr: false μ˜΅μ…˜μ„ μ‚¬μš©ν•˜λ©΄ SSR 없이 μ»΄ν¬λ„ŒνŠΈλ₯Ό λ™μ μœΌλ‘œ 뢈러올 수 μžˆμŠ΅λ‹ˆλ‹€.

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(
  () => import('@/components/hello'),
  { ssr: false }
)

λ¬Έμ œκ°€ 된 custom hook 을 μ‚¬μš©ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈλ₯Ό μœ„ 방법을 μ΄μš©ν•΄ λ™μ μœΌλ‘œ λΆˆλŸ¬μ˜¨λ‹€λ©΄

λΈŒλΌμš°μ €μ—μ„œλ§Œ λ™μž‘ν•  수 μžˆλŠ” μ½”λ“œλ₯Ό λ¬Έμ œμ—†μ΄ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

πŸ“Œ 참고자료

Advanced Features: Dynamic Import | Next.js

 

λ°˜μ‘ν˜•

πŸ’¬ λŒ“κΈ€