これまでは、状態という観点からリアクティビティについて説明してきました。しかし、それは方程式の半分に過ぎません。状態は、何かがそれに反応しなければリアクティブではなく、単なるキラキラした変数です。
反応するものはエフェクトと呼ばれます。既にエフェクトに出会っています。Svelteは、状態の変化に応じてDOMを更新するために、あなたの代わりにエフェクトを作成しますが、`$effect`ルーンを使用して独自のエフェクトを作成することもできます。
ほとんどの場合、使用するべきではありません。`$effect`は、頻繁に使用するものではなく、脱出ハッチとして考えるのが最適です。例えば、副作用をイベントハンドラに置くことができる場合は、ほとんどの場合、それが優先されます。
コンポーネントがマウントされてから経過時間を追跡するために`setInterval`を使用したいとしましょう。エフェクトを作成します。
アプリ
<script>
let elapsed = $state(0);
let interval = $state(1000);
$effect(() => {
setInterval(() => {
elapsed += 1;
}, interval);
});
</script>
「スピードアップ」ボタンを数回クリックすると、`interval`が小さくなるたびに`setInterval`を呼び出しているので、`elapsed`が速くなります。
次に「スローダウン」ボタンをクリックすると…うまくいきません。それは、エフェクトが更新されたときに古いインターバルをクリアしていないためです。クリーンアップ関数 を返すことで修正できます。
アプリ
$effect(() => {
const id = setInterval(() => {
elapsed += 1;
}, interval);
return () => {
clearInterval(id);
};
});
クリーンアップ関数は、`interval`が変更されたときにエフェクト関数が再実行される直前、およびコンポーネントが破棄されたときに呼び出されます。
エフェクト関数が実行時に状態を読み取らない場合、コンポーネントのマウント時に一度だけ実行されます。
エフェクトはサーバーサイドレンダリング中は実行されません。
前へ 次へ
1
2
3
4
5
6
7
8
9
10
<script>
let elapsed = $state(0);
let interval = $state(1000);
</script>
<button onclick={() => interval /= 2}>speed up</button>
<button onclick={() => interval *= 2}>slow down</button>
<p>elapsed: {elapsed}</p>