ข้ามไปยังเนื้อหา

$state — Reactive State

ใน React คุณประกาศ state ด้วย useState และต้องอัปเดตเสมอผ่าน setter function — คุณไม่สามารถแก้ไข state variable ตรง ๆ ได้ Svelte 5 พลิกแนวคิดนี้โดยสิ้นเชิง: $state ให้คุณได้ตัวแปรธรรมดาที่คุณ แก้ไขตรงได้เลย คอมไพเลอร์จะเขียนใหม่เป็น signals เบื้องหลัง ทำให้ UI อัปเดตอัตโนมัติ

React
function Counter() {
const [count, setCount] = React.useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}
Svelte
<script>
let count = $state(0);
</script>
<p>Count: {count}</p>
<button onclick={() => count++}>+1</button>
<button onclick={() => count = 0}>Reset</button>

ไม่มี setCount คุณเขียน count++ หรือ count = 0 ตรง ๆ — เหมือนกับตัวแปร JavaScript ธรรมดาทุกอย่าง

useState ของ React เป็น shallow — คุณต้อง spread object หรือแทนที่ array เพื่อ trigger re-render $state เป็น deeply reactive: การ mutate property ที่ซ้อนอยู่หรือเรียก array.push() จะอัปเดต UI อัตโนมัติ

React
function Profile() {
const [user, setUser] = React.useState({ name: 'Alice', age: 30 });
const [tags, setTags] = React.useState(['svelte', 'react']);
function birthday() {
setUser(u => ({ ...u, age: u.age + 1 }));
}
function addTag() {
setTags(t => [...t, 'js']);
}
return (
<div>
<p>{user.name} is {user.age}</p>
<button onClick={birthday}>Birthday</button>
<p>{tags.join(', ')}</p>
<button onClick={addTag}>Add tag</button>
</div>
);
}
Svelte
<script>
let user = $state({ name: 'Alice', age: 30 });
let tags = $state(['svelte', 'react']);
</script>
<p>{user.name} is {user.age}</p>
<button onclick={() => user.age++}>Birthday</button>
<p>{tags.join(', ')}</p>
<button onclick={() => tags.push('js')}>Add tag</button>

user.age++ และ tags.push('js') ทำงานได้เลย ไม่ต้อง spread ไม่ต้องแทนที่ — deep reactivity แบบ proxy ของ Svelte จัดการให้

React
function Form() {
const [name, setName] = React.useState('');
const [email, setEmail] = React.useState('');
const [submitted, setSubmitted] = React.useState(false);
function submit() {
setSubmitted(true);
}
if (submitted) return <p>Sent! Hello, {name}.</p>;
return (
<form onSubmit={e => { e.preventDefault(); submit(); }}>
<input value={name} onChange={e => setName(e.target.value)} placeholder="Name" />
<input value={email} onChange={e => setEmail(e.target.value)} placeholder="Email" />
<button type="submit">Send</button>
</form>
);
}
Svelte
<script>
let name = $state('');
let email = $state('');
let submitted = $state(false);
</script>
{#if submitted}
<p>Sent! Hello, {name}.</p>
{:else}
<form onsubmit={e => { e.preventDefault(); submitted = true; }}>
<input bind:value={name} placeholder="Name" />
<input bind:value={email} placeholder="Email" />
<button type="submit">Send</button>
</form>
{/if}
เพิ่มค่า counter แบบ $state ใน Svelte 5 ทำอย่างไร?
มี let user = $state({ name: "Alice" }) จะเปลี่ยน user.name เป็น "Bob" ทำอย่างไร?
เรียก tags.push("new") บน $state array แล้วเกิดอะไรขึ้น?