navbarItems을 map
을 통해 보여주기 위해, 초기에 key값을 부여하지 않은 상태로 코드를 구현하였다가, 이후 console내 log를 확인후 key값을 {index}로 부여하게끔 코드 수정후 refersh를 하였을때 적용할때 발생하였음
아래블로그에 따르면, 렌더링된 HTML(SSR, ISR 등)이 업데이트되지만 페이지 로드 후 React 코드는 업데이트되지 않을 때 발생한다고 함.
Next.js에선 이를 ‘React Hydration Error’라고 명시하였는데, 해당 문서를 살펴보면, 애플리케이션을 렌더링하는 동안 사전에 렌더링된 React 트리(SSR/SSG)와 브라우저에서 랜더링된 React 트리 간에 차이가 존재하여, React 트리가 DOM과 동기화되지 않고 예기치 않은 콘텐츠/속성이 나타날 수 있다고 합니다.
일반적으로 이 문제는 사전 렌더링과 브라우저 간에 다를 수 있는 것에 의존하는 특정 라이브러리 또는 애플리케이션 코드를 사용하기 때문에 컴포넌트의 렌더링에서 window
를 사용하여 해결 할수 있다고 합니다.
아래와 같은 예제의 경우,
function MyComponent() {
// This condition depends on `window`. During the first render of the browser the `color` variable will be different
const color = typeof window !== 'undefined' ? 'red' : 'blue'
// As color is passed as a prop there is a mismatch between what was rendered server-side vs what was rendered in the first render
return <h1 className={`title ${color}`}>Hello World!</h1>
}
Next.js 에서는 아래와 같이 에러를 해결할 수 있다고 한다.
// In order to prevent the first render from being different you can use `useEffect` which is only executed in the browser and is executed during hydration
import { useEffect, useState } from 'react'
function MyComponent() {
// The default value is 'blue', it will be used during pre-rendering and the first render in the browser (hydration)
const [color, setColor] = useState('blue')
// During hydration `useEffect` is called. `window` is available in `useEffect`. In this case because we know we're in the browser checking for window is not needed. If you need to read something from window that is fine.
// By calling `setColor` in `useEffect` a render is triggered after hydrating, this causes the "browser specific" value to be available. In this case 'red'.
useEffect(() => setColor('red'), [])
// As color is a state passed as a prop there is no mismatch between what was rendered server-side vs what was rendered in the first render. After useEffect runs the color is set to 'red'
return <h1 className={`title ${color}`}>Hello World!</h1>
}