Warning: Text content did not match. Server: "2분 전" Client: "3분 전”
Next에서 서버의 pre-render 결과와 client의 주입 시점 렌더 결과가 다를 때 발생하는 에러이다.
에러가 난 위치는 new Date()를 호출해 현재 시각과 그에 따른 시간차("n분 전")가 실시간으로 변경되므로, 렌더 시점에 따라 값에 차이가 날 수 있다.
클라이언트 컴포넌트는 클라이언트 사이드에서만 렌더링될 줄 알았는데, Next.js의 모든 페이지는 서버에서 pre-render된다고 한다.
Components in the Client Component module graph are primarily rendered on the client, but with Next.js, they can also be pre-rendered on the server and hydrated on the client.
By default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript. Pre-rendering can result in better performance and SEO.
(...) When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive (this process is called hydration in React).
— Next.js, Building Your Application, Rendering
두 가지 해결방법이 가능하다
state를 저장하는 코드를 useEffect 안에 넣으면, state가 client-side에만 저장되므로 이슈가 발생하지 않는다.
이 컴포넌트가 사용될 때마다 서버에 포함되는 것을 막고 client-side에서만 동적으로 포함된다.
const Home = dynamic(
() => import('../components/Home'),
{ ssr: false }
)
문제가 발생한 컴포넌트의 state 로직을 수정할 수 있으면 #1, 그렇지 못한 외부 라이브러리라면 #2를 선택할 수 있다.
위 케이스는 #1로 해결했다.
useEffect(()=>{
const rowData = makeRows(chats, pathname, page);
setRows(rowData);
},[chats]);
UI를 만드는 함수를 useEffect안에 옮겨두고, 받아온 데이터를 의존성 배열에 안 넣어줘서 생긴 문제였다.
주의합시다~