Basic Svelte
Bindings
Classes and styles
Advanced Svelte
Advanced reactivity
Motion
Advanced bindings
Advanced transitions
Context API
Special elements
<script module>
Next steps
Basic SvelteKit
Introduction
Routing
Loading data
Headers and cookies
Shared modules
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion
これまで、状態の観点から反応性について説明してきました。しかし、それは物事のまだ半分( half of the equation )に過ぎません。状態は、何かがそれに 反応している場合 にのみ反応性があり、そうでない場合は単なる特殊な変数( sparkling variable )です。
反応するものは effect と呼ばれます。すでにエフェクト (状態の変化に応じて DOM を更新するために Svelte が作成するエフェクト) について説明しましたが、$effect
ルーンを使用して独自のエフェクトを作成することもできます。
ほとんどの場合、
$effect
を使用するべきではありません。$effect
は頻繁に使用するものではなく、困った時の最終手段として考えるのが最適です。たとえば、副作用( side effects )を イベント ハンドラー に配置できるのであれば、ほとんどの場合それが望ましいです。
setInterval
を使用して、コンポーネントがマウントされている時間を追跡するとします。エフェクトを作成します。
<script>
let elapsed = $state(0);
let interval = $state(1000);
$effect(() => {
setInterval(() => {
elapsed += 1;
}, interval);
});
</script>
<script lang="ts">
let elapsed = $state(0);
let interval = $state(1000);
$effect(() => {
setInterval(() => {
elapsed += 1;
}, interval);
});
</script>
speed upボタンを数回クリックすると、interval
が小さくなるたびに setInterval
が呼び出されるため、elapsed
がより速く増加することがわかります。
次にslow downボタンをクリックしても、うまくいきません。これは、エフェクトの更新時に古い間隔をクリアしていないためです。クリーンアップ関数を返すことでこれを修正できます。
$effect(() => {
const id = setInterval(() => {
elapsed += 1;
}, interval);
return () => {
clearInterval(id);
};
});
クリーンアップ関数は、interval
が変更されたとき、およびコンポーネントが破棄されたときに、エフェクト関数が再実行される直前に呼び出されます。
エフェクト関数が実行時に状態を読み取らない場合は、コンポーネントがマウントされるときに 1 回だけ実行されます。
サーバー側のレンダリング中は
$effect
は実行されません。
<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>