onCleanup
コンポーネントがアンマウントされるか Effect が再実行されるときに実行されるクリーンアップ関数を登録します。
基本的な使い方
using @luna { signal, on_cleanup }
fn timer() -> @luna.Node {
let count = signal(0)
let interval = set_interval(1000, fn() {
count.update(fn(c) { c + 1 })
})
// コンポーネントアンマウント時にクリーンアップ
on_cleanup(fn() {
clear_interval(interval)
})
p([text("Count: " + count.get().to_string())])
}
onCleanup が実行されるタイミング
コンポーネント内
コンポーネントが DOM から削除されるときに実行。
Effect 内
Effect が再実行または破棄される前に実行:
let url = signal("/api/data")
effect(fn() {
let current_url = url.get()
let controller = AbortController::new()
fetch(current_url, controller.signal)
// url が変更されたとき(次の fetch 前)にクリーンアップ実行
on_cleanup(fn() {
controller.abort()
})
})
一般的なユースケース
タイマー
fn countdown(seconds : Int) -> @luna.Node {
let remaining = signal(seconds)
let interval = set_interval(1000, fn() {
remaining.update(fn(r) {
if r <= 0 { 0 } else { r - 1 }
})
})
on_cleanup(fn() { clear_interval(interval) })
p([text(remaining.get().to_string() + " 秒")])
}
イベントリスナー
fn window_resize() -> @luna.Node {
let size = signal({ width: window_inner_width(), height: window_inner_height() })
let handler = fn() {
size.set({ width: window_inner_width(), height: window_inner_height() })
}
window_add_event_listener("resize", handler)
on_cleanup(fn() {
window_remove_event_listener("resize", handler)
})
p([text("ウィンドウ: " + size.get().width.to_string() + "x" + size.get().height.to_string())])
}
よくある間違い
クリーンアップの忘れ
// 悪い: メモリリーク!
fn bad_component() -> @luna.Node {
set_interval(1000, fn() {
println("アンマウント後も実行中!")
})
div([])
}
// 良い: 適切なクリーンアップ
fn good_component() -> @luna.Node {
let interval = set_interval(1000, fn() {
println("アンマウント時にクリーンアップ")
})
on_cleanup(fn() { clear_interval(interval) })
div([])
}
試してみよう
以下を行うコンポーネントを作成:
接続を開く
受信データを表示
アンマウント時に接続を適切に閉じる
次へ
Islands アーキテクチャ → について学ぶ