リアクティブ $: ステートメント
ルーンモードでは、状態の更新への反応は$derived
と$effect
ルーンで処理されます。
レガシーモードでは、トップレベルのステートメント(つまり、ブロック内や関数内でないステートメント)は、$:
ラベルを先頭に付けることでリアクティブにすることができます。これらのステートメントは、<script>
内の他のコードの後、コンポーネントのマークアップがレンダリングされる前に実行され、その後、依存する値が変更されるたびに実行されます。
<script>
let a = 1;
let b = 2;
// this is a 'reactive statement', and it will re-run
// when `a`, `b` or `sum` change
$: console.log(`${a} + ${b} = ${sum}`);
// this is a 'reactive assignment' — `sum` will be
// recalculated when `a` or `b` change. It is
// not necessary to declare `sum` separately
$: sum = a + b;
</script>
ステートメントは、依存関係と代入によってトポロジカルに順序付けられます。console.log
ステートメントはsum
に依存しているため、ソースでは後で出現しているにもかかわらず、最初にsum
が計算されます。
複数のステートメントをブロックに入れることで組み合わせることができます
$: {
// recalculate `total` when `items` changes
total = 0;
for (const const item: any
item of items) {
total += const item: any
item.value;
}
}
リアクティブな代入の左辺は、識別子または分割代入にすることができます
$: ({ larry: any
larry, moe: any
moe, curly: any
curly } = stooges);
依存関係の理解
$:
ステートメントの依存関係はコンパイル時に決定されます。つまり、ステートメント内で参照されている(ただし代入されていない)変数です。
言い換えれば、このようなステートメントは、コンパイラが依存関係を「見ることが」できないため、count
が変更されても再実行されません
let let count: number
count = 0;
let let double: () => number
double = () => let count: number
count * 2;
$: doubled = let double: () => number
double();
同様に、依存関係が間接的に参照されている場合、トポロジカル順序付けは失敗します。z
は、更新が発生したときにy
が「ダーティ」と見なされないため、更新されません。$: z = y
を$: setY(x)
の下に移動すると修正されます
<script>
let x = 0;
let y = 0;
$: z = y;
$: setY(x);
function setY(value) {
y = value;
}
</script>
ブラウザのみのコード
リアクティブステートメントは、ブラウザだけでなくサーバーサイドレンダリング中にも実行されます。これは、ブラウザでのみ実行する必要があるコードは、if
ブロックでラップする必要があることを意味します
$: if (browser) {
var document: Document
document.Document.title: string
Contains the title of the document.
title = title;
}