Action state

액션 상태

Track a form action result and its pending flag as one state flow.

···
html
<div class="scene"><div class="form"><span>email</span><div class="field">a@b.test</div><div class="button" id="button">SAVE</div></div><div class="steps"><span id="idle">idle</span><span id="pending">pending</span><span id="result">result</span></div><div class="message" id="message">Ready to submit</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}.form{display:grid;grid-template-columns:1fr 2fr 1fr;align-items:center;gap:7px}.field{border:1px solid var(--line);border-radius:5px;padding:.5em;overflow:hidden;white-space:nowrap;font-size:.8em}.button{background:var(--accent);color:var(--bg);border-radius:6px;text-align:center;padding:.5em;font-weight:700}.steps{display:flex;justify-content:space-between;margin:clamp(23px,8vmin,55px) 0 16px}.steps span{width:30%;padding:.4em;border:1px solid var(--line);border-radius:6px;text-align:center}.steps .on{border-color:var(--accent);color:var(--accent)}.message{text-align:center;color:var(--muted)}
js
let n=0;function tick(){const s=n%4;["idle","pending","result"].forEach((id,i)=>document.getElementById(id).classList.toggle("on",i===Math.min(s,2)));document.getElementById("button").textContent=s===1?"SAVING…":"SAVE";document.getElementById("message").textContent=["Ready to submit","Sending action","Saved","Validation error"][s];n++}tick();setInterval(tick,850)

useActionState exposes the action result, an action function, and a pending flag. Each submission can derive a new result from previous state and form data.

The demo moves through idle, pending, success, and error, updating both the button and message. Plan how to retain input and errors after failure.

When to use

Use it when a form should render submission progress and result together.

Open as page ↗