React 브라우저 경계

React browser boundary

서버에서 의미 있게 렌더할 수 없는 부분만 Suspense fallback으로 대체합니다.

···
html
<div class="scene"><div class="steps"><span id="serverStep">SERVER HTML</span><span id="clientStep">BROWSER</span></div><div class="window"><div class="title">YOUR LOCAL TIME</div><div class="display" id="display">Loading timezone…</div><div class="caption" id="caption">Suspense fallback in HTML</div></div><div class="rail"><i id="progress"></i></div></div>
css
.scene{width:min(94vw,800px);height:min(86vh,320px);position:relative;overflow:hidden;display:flex;flex-direction:column;justify-content:space-between;border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:clamp(9px,2.4vmin,20px);font:500 clamp(15px,4vmin,18px)/1.3 var(--font-sans,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif)}.scene b,.scene strong{font-weight:700}.label{color:var(--muted)}.code{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.pill{border:1px solid var(--line);border-radius:8px;padding:.4em .65em;background:var(--bg)}.active{border-color:var(--accent)!important;color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 10%,var(--surface))!important}.steps{display:flex;justify-content:space-between;font:700 clamp(12px,3.3vmin,15px) ui-monospace,monospace;color:var(--muted)}.steps .on{color:var(--accent)}.window{flex:1;min-height:80px;border:1px solid var(--line);border-radius:10px;margin:8px 0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;background:var(--bg)}.title{font:700 clamp(12px,3vmin,14px) ui-monospace,monospace;color:var(--muted)}.display{font-weight:700;font-size:clamp(16px,5vmin,24px);color:var(--accent)}.caption{font-size:clamp(12px,3vmin,15px);color:var(--muted)}.rail{height:5px;background:var(--line);border-radius:5px}.rail i{display:block;height:100%;width:45%;background:var(--accent);border-radius:5px;transition:width .5s}
js
const zone=Intl.DateTimeFormat().resolvedOptions().timeZone;let client=false;function tick(){client=!client;document.getElementById("display").textContent=client?zone:"Loading timezone…";document.getElementById("caption").textContent=client?"hydrated: browser value":"Suspense fallback in HTML";document.getElementById("serverStep").classList.toggle("on",!client);document.getElementById("clientStep").classList.toggle("on",client);document.getElementById("progress").style.width=client?"100%":"45%"}tick();setInterval(tick,2200)

React DOM 19.3의 browser()를 use(browser())로 읽으면 컴포넌트가 서버 렌더 중 중단되고 가장 가까운 Suspense fallback을 출력합니다. 브라우저에서는 중단하지 않으므로 하이드레이션 후 브라우저 전용 값을 렌더할 수 있습니다.

데모는 서버 HTML의 대기 표시가 브라우저 시간대 위젯으로 바뀌는 순서를 보여줍니다. 서버에서 의미 있는 초기 값을 만들 수 있다면 그 값을 렌더하는 편이 낫고, 이 경계는 필요한 부분에만 둡니다.

언제 쓰나

로컬 시간대나 브라우저 저장소처럼 서버에서 알 수 없는 값으로만 UI를 만들 때 사용합니다.

페이지로 열기 ↗