상태·렌더·커밋

State, render, commit

상태 업데이트가 새 UI 계산을 예약하고, 렌더 결과가 커밋될 때 실제 화면이 바뀝니다.

···
html
<div class="demo"><div class="head"><strong>STATE → UI</strong><span id="phase">update</span></div><div class="scene"><div class="chip box" id="state">state<br><b>0</b></div><span class="arrow">→</span><div class="chip box" id="render">render<br><b>0</b></div><span class="arrow">→</span><div class="chip box" id="commit">DOM<br><b>0</b></div></div><div class="foot"><span>update → render → commit</span><span>tap to step</span></div></div>
css
.demo{width:min(92vw,660px);height:min(86vh,310px);border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:clamp(10px,2.5vmin,20px);display:flex;flex-direction:column;gap:clamp(6px,1.7vmin,12px);box-shadow:0 10px 35px rgba(0,0,0,.07);font:500 clamp(10px,2.8vmin,15px)/1.35 ui-monospace,SFMono-Regular,Consolas,monospace}
.head,.foot{display:flex;align-items:center;justify-content:space-between;gap:8px}.head strong{color:var(--accent);font-size:1.05em}.foot{color:var(--muted);font-size:.85em;min-height:1.4em}.scene{flex:1;min-height:0;position:relative;display:flex;align-items:center;justify-content:center;gap:clamp(5px,1.5vmin,12px)}.chip{border:1px solid var(--line);background:var(--bg);border-radius:7px;padding:.4em .6em;text-align:center}.on{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 12%,var(--surface))!important;color:var(--accent)!important}.dim{opacity:.42}.arrow{color:var(--muted)}
.box{width:25%;height:60%;display:flex;flex-direction:column;justify-content:center}.box b{font-size:clamp(17px,6vmin,34px)}
js
let count=0,rendered=0,committed=0,step=0;const ids=["state","render","commit"];function advance(){if(step===0)count++;if(step===1)rendered=count;if(step===2)committed=rendered;[count,rendered,committed].forEach((v,i)=>{const box=document.getElementById(ids[i]);box.querySelector("b").textContent=v;box.classList.toggle("on",i===step)});document.getElementById("phase").textContent=["update","render","commit"][step];step=(step+1)%3}advance();const timer=setInterval(advance,800);document.querySelector(".demo").addEventListener("pointerdown",()=>{clearInterval(timer);advance()})

React에서 상태를 바꾸면 컴포넌트가 새 결과를 계산하도록 렌더가 예약됩니다. 렌더 단계는 다음 UI를 계산하고, 커밋 단계가 필요한 DOM 변경을 적용합니다.

데모는 카운터 상태, 계산된 결과, 화면에 반영된 값을 따로 보여줍니다. 단계 사이에는 숫자가 잠시 달라져도 최종 커밋 뒤에는 일치합니다. 직접 DOM을 고쳐 상태와 다른 값을 만드는 방식은 피하세요.

언제 쓰나

상태 업데이트 후 화면이 언제 바뀌는지 이해하거나 렌더와 이펙트의 역할을 구분할 때 유용합니다.

페이지로 열기 ↗