Signals
Signal は値を保持し、変更時にサブスクライバーに通知するリアクティブコンテナです。
Signal の作成
import { createSignal } from '@luna_ui/luna';
// 基本的な Signal
const [count, setCount] = createSignal(0);
// 初期値付き
const [name, setName] = createSignal("Luna");
// 複雑な型
const [user, setUser] = createSignal({ name: "Alice", age: 25 });
値の読み取り
Signal を関数として呼び出して値を読み取ります:
const [count, setCount] = createSignal(5);
console.log(count()); // 5
// JSX 内 - リアクティブバインディングを作成
<p>Count: {count()}</p>
値の書き込み
直接設定
const [count, setCount] = createSignal(0);
setCount(5); // 5 に設定
setCount(10); // 10 に設定
関数による更新
前の値に基づいて更新:
const [count, setCount] = createSignal(0);
setCount(c => c + 1); // インクリメント
setCount(c => c * 2); // 2倍
Peek(追跡なしで読み取り)
依存関係を作成せずに Signal を読み取る:
import { createSignal, createEffect } from '@luna_ui/luna';
const [count, setCount] = createSignal(0);
const [other, setOther] = createSignal(0);
createEffect(() => {
// この Effect は `other` が変更されたときのみ再実行
// count を読み取っているにもかかわらず
console.log(count.peek(), other());
});
オブジェクトを持つ Signal
オブジェクトを扱う場合、更新をトリガーするには新しいオブジェクトを作成する必要があります:
const [user, setUser] = createSignal({ name: "Alice", age: 25 });
// 間違い - ミューテーションは更新をトリガーしない
user().age = 26;
// 正しい - 新しいオブジェクトを作成
setUser(u => ({ ...u, age: 26 }));
複数の Signal
Signal は独立しています。一つを変更しても他に影響しません:
const [firstName, setFirstName] = createSignal("John");
const [lastName, setLastName] = createSignal("Doe");
// それぞれ独立して更新
<p>First: {firstName()}</p> {/* firstName 変更時に更新 */}
<p>Last: {lastName()}</p> {/* lastName 変更時に更新 */}
試してみよう
2つの入力(姓、名)を持つフォームを作成し、フルネームを表示:
解答
function NameForm() {
const [firstName, setFirstName] = createSignal("");
const [lastName, setLastName] = createSignal("");
return (
<div>
<input
value={firstName()}
onInput={(e) => setFirstName(e.target.value)}
placeholder="名"
/>
<input
value={lastName()}
onInput={(e) => setLastName(e.target.value)}
placeholder="姓"
/>
<p>フルネーム: {firstName()} {lastName()}</p>
</div>
);
}
次へ
Effects → について学ぶ