Next JS Pre-rendering : Hydration

Min Su Kwon·2021년 8월 28일
0
post-thumbnail

궁금증

서버로부터 HTML 파일을 넘겨받는 경우에서, 살짝 이상한 점이 있다. 브라우저의 콘솔을 확인해보면, 서버에서 HTML 파일 생성 과정에서 찍혔던 console.log 들이 여기서도 보인다. 분명 다 만들어서 그대로 HTML 넘기는 걸로 생각했는데 왜이런걸까?

이유는 서버로부터 최초 렌더링 결과물인 HTML을 받아온 뒤, 리액트에서 Hydration 단계를 거치기 때문이다. 서버사이드에서 내려주는 HTML은 자바스크립트 이벤트 리스너들이 붙어있지 않은데, Hydration 단계에서 이런 부분들을 다시 붙여주게된다.

Hydration은 뭘까

아래와 같이 onClickHeading이라는 핸들러를 선언한 뒤 div 태그에 붙이고 빌드를 한 뒤,

직접 빌드된 HTML을 열어보면, 코드 단에서 붙여놓은 이벤트 핸들러가 붙어있지 않아 동작하지 않는다.

반면 hydrate 된 이후의 결과를 보면, 코드에서 지정한대로 정상 동작한다.

요약해보면, 서버에서 내려주는 HTML은 고정되어 있는 그림 같은 느낌이고, 여기에 사용자가 상호작용할 수 있도록 자바스크립트 이벤트 리스너를 붙이려면 Hydration 과정이 필요한 것이다. 따라서, 이 Hydration 과정에서 컴포넌트 렌더 함수가 클라이언트 사이드에서 실행되게 된다.

가끔 마주하게 되는 오류 : Text content did not match

리액트 앱 개발 과정에서 위와 같은 오류를 가끔 보게 되는데, 이 오류가 hydration 과정에서 생기는 오류다. 간단하게 말하면, 서버에서 내려준 HTML 결과물과, Hydration 과정에서 만들어낸 HTML 결과물이 다를때 발생하는 오류다.

리액트에서는 서버사이드 렌더링이 이뤄졌을 시에, 그 결과로 나온 HTML과 클라이언트에서 직접 렌더링한 HTML 결과물이 똑같을 것으로 기대하는데, 기대를 충족하지 못했으니 개발환경에서는 warning을 뱉게된다.

위 코드에서는 Date.now().toLocaleString() 부분이 문제였다. 서버사이드 렌더링때의 now와 hydration 할 때의 now가 당연히 차이가 있으니 결과물 HTML이 차이가 나고, 이에 따라서 content mismatch warning이 발생한 것이다.

차이나는 부분이 위 예시처럼 간단한 텍스트인 경우 리액트가 결과물을 바꿔서 보여주기도 하지만, 모든 부분을 하나하나 비교하기에는 비용이 너무 많이 들어가기 때문에 mismatch가 뜬 모든 부분을 바꿔주지 않는다. 따라서, 개발 과정에서 이 오류가 뜰 경우 코드를 고쳐주는 것이 좋다.

Reference

profile
이제 막 커리어를 시작한 소프트웨어 엔지니어입니다. 배운 것을 정리하면서 조금 더 깊이 이해하려는 습관을 들이려고 합니다. 피드백은 언제나 환영입니다.

0개의 댓글