next.js는 react의 라이브러리 프레임워크로, 가장 큰 특징은 서버사이드 렌더링을 한다는 것입니다. 사실 실제로 작업을 할 때는 next.js와 react의 큰 차이점을 거의 느끼지 못했기 때문에 다음과 같은 에러를 처음 봤을 때 이게 왜 생기는 문제인지 바로 알지 못했습니다.
Warning: Expected server HTML to contain a matching
<svg>
in<div>
당시 하고 있었던 작업은 다국어를 지원하는 드롭다운을 만들면서 아래와 같이 국기 svg와 언어명이 나타나도록 하는 것이었습니다.
그런데 드롭다운에 svg를 추가했을 때 상술했던 warning 에러가 발생하는 것이었습니다. 워닝 문구로 계속 검색하면서 스택오버플로우나 블로그 등에서 본 해결책대로 적용해봐도 계속 에러가 발생했는데 우연히 찾은 블로그에서 해결책을 찾았습니다. 해당 블로그에서는 이 에러에 대해 서버사이드 렌더링 시의 html과 클라이언트 사이드 렌더링 시의 html이 일치하지 않아서 발생하는 에러로 추측합니다. 그래서 실제로 브라우저의 쿠키를 삭제하면 해당 에러가 발생하지 않는다는 것을 확인할 수 있었습니다.
브라우저 쿠키 삭제
브라우저의 쿠키를 삭제해서 html을 아예 새롭게 렌더링하면 해당 에러가 발생하지 않습니다. 브라우저가 기억하고 있는 html이 없기 때문입니다. 다만 계속 테스트를 하면서 작업을 할 때는 브라우저의 쿠키를 계속 삭제한다는 게 번거롭기 때문에 다음과 같이 코드를 추가해 해당 문제를 해결했습니다.
useEffect를 사용해서 렌더링 후 상태 업데이트
useEffect를 사용해서 렌더링 후 상태를 업데이트 해주는 것입니다.
const [mounted, setMounted] = useState<boolean>(false);
useEffect(() => {
setMounted(true);
}, []);
return (mounted && <...>)
사실 이 경고가 뜬다고 해서 작업을 하는데 문제가 있다거나 하지는 않습니다. 다만 작업 중 계속해서 콘솔에 뜨는 경고를 제거하고 싶을 때 이 방법을 사용하면 됩니다.
클라이언트 사이드 렌더링과 서버 사이드 렌더링에 대해서는 막연하게 '어떤 점'이 다르다는 걸 알고만 있는 상태였는데 해당 문제를 겪으면서 렌더링 시점에 대해 생각해보는 계기가 되었습니다.
덕분에 hydration 에러 해결할 수 있었어요 감사합니다!!