일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 참조자료형
- JavaScript
- CDD
- Javascript #코드스테이츠
- 코드스테이스
- 회고
- Router
- WAI-ARIA
- JS
- css in js
- html
- 자바스크립트
- 프로토타입
- 계산기
- 객체지향
- 프론트엔드
- OOP
- 개발자
- css
- codestates
- frontend
- condestates
- 원시자료형
- self reliance
- codestate
- cta button
- cta버튼
- Prototype
- 코드스테이츠
- 호스트인식
- Today
- Total
jh.nrtv
[error]Error: Hydration failed because the initial UI does not match what was rendered on the server. 본문
[error]Error: Hydration failed because the initial UI does not match what was rendered on the server.
wlgus3 2023. 7. 17. 20:14
Next.js로 진행하는 프로젝트에서 아래의 에러를 만났다.
이 에러에 대해서 공부하면서 다시 공부하게 된 것이 두 가지 있다.
1. Hydration 이슈
먼저 에러 문구에 적힌 Hydration이란 무엇일까?
Hydration은 이미 서버에서 랜더링된 html을 client단에서 자바스크립트를 통해서 이벤트 처리, 상태관리 등이 가능한 fully interactive application 으로 바꾸는 과정을 뜻한다. 즉 서버에서 정적인 html을 받아들이고 파싱해서 초기 렌더링을 수행하고 JS코드로 해당 html을 (리액트 트리에 맞게)동적인 페이지로 전환하는 것을 말한다. 이를 통해서 앱의 초기 로딩 속도를 개선하고 SEO를 향상시킬 수 있다.
SPA vs fully interactive application
SPA (Single Page Application)는 사용자가 웹 애플리케이션을 이용하는 동안 페이지를 새로고침하지 않고 단일 페이지로 동작하는 웹 애플리케이션을 말합니다. SPA는 초기에 한 번만 페이지를 로드하고, 이후에는 필요한 데이터와 리소스를 동적으로 로드하여 사용자 경험을 향상시킵니다. 일반적으로 SPA는 JavaScript 프레임워크 또는 라이브러리 (예: React, Angular, Vue 등)를 사용하여 클라이언트 측에서 렌더링되며, 서버로부터 데이터를 비동기적으로 가져와서 렌더링합니다.
Fully interactive application (전적으로 상호작용하는 애플리케이션)은 사용자와의 상호작용이 매우 높은 애플리케이션을 말합니다. 이러한 애플리케이션은 사용자 입력에 대해 즉각적으로 반응하고, 필요한 데이터를 동적으로 로드하며, 화면을 업데이트하고 재렌더링합니다. Fully interactive application은 보통 SPA의 형태를 가지며, 모던 웹 기술과 프레임워크를 사용하여 구현됩니다.
따라서, "fully interactive application"은 일반적으로 "SPA"의 세부적인 특성을 강조하는 데 사용될 수 있습니다. SPA가 fully interactive하다고 표현되기도 합니다. 하지만 "fully interactive application"은 SPA에 국한되지 않고, 웹 기술을 사용하여 사용자와 높은 상호작용을 갖는 다른 유형의 웹 애플리케이션도 포함합니다.
따라서 위 에러는 기존에 서버부터 받아들인 pre-rendered 된 html과 리액트 트리가 일치하지 않아서 오류를 뱉어내는 것인데
이를 해결하기 위해서 useEffect를 사용하거나 dynamic import를 사용하거나 useEffect()를 사용해서 client page에서만 동작하도록 해결한다.
나는 메인페이지에 임포트 되어있으며, 코드가 복잡한 지도표시 컴포넌트인 map.js를 사용하는 코드에 문제가 있을 것이라고 판단했다. 하지만 나는 위 두 가지 방법에 따르면 문제가 없었다. 이미 dynimic import와 useEffect 모두를 사용해서 랜더링 되도록 했기 때문이다.
const DynamicMap = dynamic(() => import("./component/map"), {
loading: () => <p>지도를 불러오는중 ...</p>,
});
Text content does not match server-rendered HTML
Using App Router Features available in /app
nextjs.org
Next.js의 Hydrate란?
Next.js 프레임워크의 동작원리를 제대로 파악하고 있는 개발자라면 Hydrate에 대해선 이미 익숙한 용어일 것이다. 그러나 Next.js의 주요 동작 방식 중 하나임에도, 눈에 잘 띄지 않아 놓치기도 쉬운
helloinyong.tistory.com
2. 블럭요소와 인라인요소
다시 에러코드를 찬찬히 읽어보니 에러가 <div> 와 <p> 태그에 대해서 말하고 있는 것을 발견했다.
알고보니 footer.tsx파일이 <p> 태그 안에 <div> 태그가 포함되어 있기 때문에 html 요소의 중첩관계가 올바르지 않아서 생긴 이슈였다.
export default function Footer() {
return (
<div className="footer">
<nav></nav>
<p>
<span>Contact : pullhorizon@gmail.com</span>
<br />
<span>
Copyright 2023. <span className="bold">Uppernight.</span> All Rights Reserved.
</span>
<div style={{ fontSize: "130%", right: "5vw", position: "absolute", marginTop: "2vw" }}>
UpperNight
<span>
<Image src={logoimg} className="mobile_logoimg" alt="logo image" height="35" width="35" />
</span>
<span>
<Image src={logoimg} className="web_logoimg" alt="logo image" height="50" width="50" />
</span>
</div>
</p>
</div>
);
}
html 태그에는 블럭요소, 인라인 요소가 있다.
- 블럭요소 : 하나의 태그가 브라우저에서 좌우공간을 다 차지하면서 독립적인 덩어리 공간을 가지는 요소
-> <div>,<table>,<h1>~<h6>,<p>,<form>,<ul>,<ol>,<li>,<dl>,<dt>,<dd>,<pre>,<blockquote>
- 인라인요소 : 하나의 태그가 브라우저에서 실제로 코딩된 그 영역만 차지하여 좌우로 다른 태그가 나란히 위치할 수 있는 요소. 텍스트레벨요소라고도 함.
-> <span>,<a>,<br>,<em>,<strong>,<input>,<label>,<img>
블럭요소는 내부에 블럭요소와 인라인요소를 포함할 수 있다.
인라인요소는 내부에 블럭요소를 포함할 수 없다.
하지만 블럭요소 중에서도 인라인 요소만 포함할 수 있는 것들이 있다고 한다. <h1>~<h6> 와 <p> 이다.
위 코드를 보면 <p> 태그 하위에 <div> 가 포함된 것을 확인할 수 있다.
따라서 <p>를 블럭 요소도 포함할 수 있는 <div>로 바꾸어 주었더니 에러가 해결되었다.
에러를 만나서 해결하는 와중에 의도치않게 중요한 개념을 다시 공부하는 계기가 되었다.
에러를 만나도 성장할 기회로 생각하는 여유로움이 필요한 것 같다 ~
'Error' 카테고리의 다른 글
간단 회고 - 데이터의 종류를 다시 한 번 생각하며 핸들링하자! (0) | 2024.08.12 |
---|---|
소수 데이터 핸들링하기 ( 부동 소수점 연산의 오차) (0) | 2024.08.06 |
[error] 배포시 미디어쿼리 적용 안되는 에러 (0) | 2023.07.17 |
[error] Type error: 'result' is possibly 'null' (0) | 2023.07.15 |
[error] vercel배포중 Module not found: Can't resolve 'perf_hooks' ReactJS (0) | 2023.07.14 |