リアクティビティ
コンポーネント関数は、ウィンドウ(または親)がマウントされるときに 1 回実行されます。シグナルはツリー全体を作り直さずに、テキストとプロパティを最新に保ちます。
#リアクティブな状態
ui.CreateSignal でシグナルを作ります。テキストとプロパティで読みます:ui.Text("Count: ", count())、.Width(width())。イベントハンドラーは書き込みを自動的にバッチ処理します。
func TextExample() *ui.Element {
count, setCount := ui.CreateSignal(0)
return ui.View().Children(
ui.Text(
"Count: ",
count(),
).FontSize(20),
ui.Button().Child("Increment").OnClick(func() { setCount(count() + 1) }),
)
}initial := count() はスナップショットです。値を更新し続けるときは、あとでシグナルを再度読んでください。シグナルを子として渡すこともできます。ui.Text("Count: ", count) は接頭辞を残し、数字だけを更新します。
カスタムコンポーネントは普通の int、string、構造体の引数を取ります。LineItem(product, quantity()) は quantity を購読し続けます。
#派生状態
他のシグナルから計算する値には ui.CreateMemo を使います。
func DerivedExample() *ui.Element {
count, setCount := ui.CreateSignal(0)
doubled := ui.CreateMemo(func() int { return count() * 2 })
return ui.View().Children(
ui.Text("Doubled: ", doubled()),
ui.Button().Child("Increment").OnClick(func() { setCount(count() + 1) }),
)
}#副作用とクリーンアップ
購読やウィンドウタイトルなど、ツリーの外の作業には ui.CreateEffect を使います。マウント後に実行され、読んだ値が変わると再度実行されます。ui.OnCleanup は次の実行の前と、コンポーネントがなくなるときに実行されます。
func EffectExample() *ui.Element {
topic, setTopic := ui.CreateSignal("Inbox")
ui.CreateEffect(func() {
current := topic()
log.Print("Subscribe: ", current)
ui.OnCleanup(func() { log.Print("Unsubscribe: ", current) })
})
return ui.View().Children(
ui.Text("Watching: ", topic()),
ui.Button().Child("Switch topic").OnClick(func() {
if topic() == "Inbox" {
setTopic("Archive")
} else {
setTopic("Inbox")
}
}),
)
}テキストとプロパティは直接更新します。effect の中で UI を作り直さないでください。
#更新のバッチ処理
クリックハンドラーはすでに書き込みをバッチします。ほかの場所では関連する書き込みを ui.Batch で包み、観察者には 1 つの結果だけが見えるようにします。ui.Untrack は購読せずにシグナルを読みます。シグナルの読み書きは UI ゴルーチンで行い、バックグラウンドの結果は ui.Async または native.Dispatch で届けます。
func BatchedExample() *ui.Element {
first, setFirst := ui.CreateSignal("Ada")
last, setLast := ui.CreateSignal("Lovelace")
ui.CreateEffect(func() { log.Print(first() + " " + last()) })
applyProfile := func() {
ui.Batch(func() {
setFirst("Grace")
setLast("Hopper")
})
}
return ui.View().Children(
ui.Text(first(), " ", last()),
ui.Button().Child("Apply profile").OnClick(applyProfile),
)
}