서버 컴포넌트의 직접 Context 렌더

Direct Context rendering in RSC

서버 컴포넌트가 클라이언트 Context를 직접 렌더해 자식에게 값을 제공합니다.

···
html
<div class="scene"><div class="node server" id="server">SERVER <b>theme: mint</b></div><div class="connector"><i id="token"></i></div><div class="node context" id="context">&lt;ThemeContext value&gt;</div><div class="connector"><i id="token2"></i></div><div class="node client" id="client">CLIENT CHILD <b id="received">waiting</b></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}.scene{justify-content:center;gap:0}.node{width:100%;border:1px solid var(--line);border-radius:8px;padding:clamp(5px,2vmin,9px);display:flex;justify-content:space-between;gap:5px;align-items:center;font:700 clamp(12px,3vmin,15px) ui-monospace,monospace;min-height:clamp(32px,12vmin,46px)}.node b{color:var(--accent)}.node.on{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 12%,var(--surface))}.context{text-align:center;justify-content:center}.connector{height:clamp(8px,2.4vmin,16px);display:flex;justify-content:center;position:relative}.connector:before{content:"";height:100%;border-left:2px solid var(--line)}.connector i{position:absolute;top:0;width:8px;height:8px;border-radius:50%;background:var(--accent);opacity:0}.connector i.run{opacity:1;animation:down .6s linear forwards}@keyframes down{to{top:100%}}
js
let step=0;function tick(){step=(step+1)%4;for(const id of ["server","context","client"])document.getElementById(id).classList.remove("on");document.getElementById("token").classList.remove("run");document.getElementById("token2").classList.remove("run");document.getElementById("received").textContent=step===3?"theme: mint":"waiting";if(step===0)document.getElementById("server").classList.add("on");if(step===1){document.getElementById("context").classList.add("on");void document.getElementById("token").offsetWidth;document.getElementById("token").classList.add("run")}if(step===2){document.getElementById("context").classList.add("on");void document.getElementById("token2").offsetWidth;document.getElementById("token2").classList.add("run")}if(step===3)document.getElementById("client").classList.add("on")}tick();setInterval(tick,800)

React 19.3에서는 서버 컴포넌트가 클라이언트 모듈에서 만든 Context를 가져와 <Context value={...}>를 직접 렌더할 수 있습니다. 값만 전달하는 별도 클라이언트 Provider 래퍼를 만들 필요가 줄어듭니다.

데모는 서버가 읽은 사용자 설정이 Context를 거쳐 클라이언트 자식에 도달하는 트리를 보여줍니다. 서버 컴포넌트에서 Context를 생성하거나 useContext로 읽을 수 있다는 뜻은 아닙니다.

언제 쓰나

서버가 읽은 설정을 여러 클라이언트 자식에 Context로 제공할 때 사용합니다.

페이지로 열기 ↗