✅ 문제
- 리액트로 했을땐 문제가 안났던 jsx 코드가 nextJS로 마이그레이션 하니 오류가 났다.
- 근데 처음 렌더시만 오류가 뜨고 이후 화면에 UI가 제대로 나타나고 문제없이 동작도 됐다.
🔆 Hydration이란?
참조자료
ReactDOM.render(element, container[, callback])
ReactDOM.hydrate(element, container[, callback])
hydrate는 render()와 비슷하다.
그러나 hydrate는
- server에 의해 pre-render된 html의 DOM tree를 렌더하고
- 이 tree에 이벤트 핸들러를 바인딩하는 역활을 한다.
이후에 사용자는 interactive 가능하게 되는 것이다.
※ Hydration을 사용하면 좋은점
- 초기 로딩속도 감소
클라이언트에서 렌더링될 때는 paint함수가 호출되서 실제로 페이지를 그리는게 아니라, pre-render한 dom tree와 매칭만 하는 것이다. 따라서 성능적으로도 더 좋다.
- 검색엔진 최적화
✅ 해결 과정
원인파악 - 공식문서 조회
- ssr에서 처음에 내려주는 UI(pre-render)와 브라우저에서 첫 번째로 렌더되는 UI 트리간에 차이가 있기 때문에 난 문제다.
- 첫 번째 렌더는 React의 특징인 Hydration이라고 불린다.
- 즉, React 트리가 DOM과 동기화되지 않아 발생하게 되는 문제다.
해결 방법 - 공식문서 조회
방법1. 환경에 따라 다른 UI 나타내는 코드 없애기
- node에서 실행시는 최상위 객체가 window가 아니다. 때문에 color는 blue가 된다.
- 그러나 브라우저에서 실행시는 최상위 객체가 window다. 때문에 color는 red가 된다.
- 이렇게 환경에 따라 다른 UI가 되면, 서버에서 만든 html파일과 브라우저에서 처음 렌더하는 html 내용이 다르므로 오류가 난다.
방법2. p태그 안에 div태그가 있는 것 처럼, 요소의 순서 맞추기
✅ 나의 해결 방법
- 내 코드의 경우 p태그 안에 ul태그도 없이 li태그만 들어있었다.
어떻게 이런 코드가 됐는지... 코드를 여러번 수정하다 보니 미쳐 파악하지 못하고 진행한 것 같다.
- 이 코드를 div태그 안에 p태크가 들어있는 식으로 수정하여 해결했다.
🤔 궁금증
react로만 개발했을 땐 p태그 안에 li태그를 써도 문제없이 잘 나왔는데, 왜 nextJS로 바꾸니 오류가 나는걸까?
→ 추측컨대, 리액트는 그냥 js가 실행하면서 이런 dom tree도 그려졌지만
server에서 html을 만드는 과정에선 이런 문제를 다르게 실행하는 것 같다.
참조자료
https://nextjs.org/docs/messages/react-hydration-error
https://helloinyong.tistory.com/315
https://fourwingsy.medium.com/next-js-hydration-%EC%8A%A4%ED%83%80%EC%9D%BC-%EC%9D%B4%EC%8A%88-%ED%94%BC%ED%95%B4%EA%B0%80%EA%B8%B0-988ce0d939e7