@senspond
>
NextJs - Text content did not match. Server : "A" Client: "B" 오류 를 만나고 해결한 방법을 정리
RgbitCode 블로그를 Nextjs 로 개발하면서 만나게 되었던 오류이다.
테마 기능을 적용하면서 브라우저 콘솔에 다음과 같은 오류가 발생하였다.
NextJS 는 서버사이드랜더링(SSR)을 지원하는 프레임워크이다. 기본적으로 Next.js는 모든 페이지를 사전 랜더링(pre-rendering)하게 된다. 이것은 Next.js가 미리 각 페이지별로 HTML을 생성한다는 것을 의미하며, 클라이언트 측의 자바스크립트로 모든 것을 수행하는 대신. 사전 랜더링을 통해 성능과 SEO가 향상될 수 있다.
서버에서 사전 랜더링한 HTML 과 클라이언트에서 랜더링한 HTML이 서로 불일치 하기 때문에 발생하였기 때문이다.
서버에서 사전랜더링 한 HTML과 클라이언트가 랜더링한 HTML가 일치되도록 클라이언트,서버간 상태를 공유할 수 있도록 구현을 하거나
서버에서 랜더링을 하지 않고 클라이언트에서만 랜더링 하도록 컴포넌트를 작성하면 된다. 여기서는 오류를 무시하거나 클라이언트에서만 랜더링 되도록 하는 방법으로 정리해보았다.
에러로그를 출력을 하지 않도록 해버리는 방법이다. 문제를 발생시키는 컴포넌트에 suppressHydrationWarning를 달아주면 된다. 그러나 에러로그를 무시해버리는 방법이기에 권장되는 방법은 아니다.
<Component suppressHydrationWarning />
useEffect를 사용해 client에서만 랜더링 되도록 만드는 방법이다.
export default function Home() {
const cook = new Cookies();
const [session, setSession] = useState();
// `setCookie` and `deleteCookie` code here
useEffect(() => {
setSession(cook.get("key"));
}, []);
return (
<div className={styles.container}>
<button onClick={() => setCookie()}>Save Cookie</button>
<button onClick={() => deleteCookie()}>Delete Cookie</button>
{session ? <>I'm in</> : <>I'm out</>}
</div>
);
}
nextjs 에서 지원하는 dynamic import {ssr : false} 를 통하는 방법이다. 구성요소가 서버에 포함되지 않고 클라이언트 측에서만 동적으로 로드되도록 만드는 것이다.
const Home = dynamic(
() => import('../components/Home'),
{ ssr: false }
)
'use client';
import dynamic from 'next/dynamic';
type Props = { children: JSX.Element };
const NoSSRRendering = ({ children }: Props) => {
return children;
};
export default dynamic(() => Promise.resolve(NoSSRRendering), {
ssr: false,
});
필자는 위와 같은 공통 컴포넌트를 구현하고 서버에서 사전랜더링이 필요하지 않은 컴포넌트에는 다음과 같이 감싸주기로 했다. 이런 오류를 만날때마다 또 반복적인 코드를 작성하는것이 귀찮기 때문이었다.
이글은 아래 링크의 글을 참고하여 작성되었습니다.
안녕하세요. Red, Green, Blue 가 만나 새로운 세상을 만들어 나가겠다는 이상을 가진 개발자의 개인공간입니다.
현재글에서 작성자가 발행한 같은 카테고리내 이전, 다음 글들을 보여줍니다
@senspond
>