Skip to main content

前の例でアプリは動きましたが、微妙なバグがあります。ストアはサブスクライブされますが、決してアンサブスクライブされません。仮に、コンポーネントが何度もインスタンス化および破棄されるなら、 メモリリーク が発生することになるでしょう。

まず、App.svelteunsubscribe を宣言します。

ts
const unsubscribe = count.subscribe((value) => {
countValue = value;
});

subscribe メソッドを呼ぶと unsubscribe 関数が返ります.

unsubscribe が宣言されましたが、さらに、例えば onDestroy lifecycle hook などで呼び出される必要があります。

<script>
	import { onDestroy } from 'svelte';
	import { count } from './stores.js';
	import Incrementer from './Incrementer.svelte';
	import Decrementer from './Decrementer.svelte';
	import Resetter from './Resetter.svelte';

	let countValue;

	const unsubscribe = count.subscribe((value) => {
		countValue = value;
	});

	onDestroy(unsubscribe);
</script>

<h1>The count is {countValue}</h1>

ただし、このやり方は、特にコンポーネントが複数のストアにサブスクライブしている場合に、少し定型的になり始めます。代わりに、Svelte には巧妙な工夫が施されています。ストア名の前に $ を付けることで、ストアの値を参照できます。

<script>
	import { count } from './stores.js';
	import Incrementer from './Incrementer.svelte';
	import Decrementer from './Decrementer.svelte';
	import Resetter from './Resetter.svelte';
</script>

<h1>The count is {$count}</h1>

自動サブスクリプションは、コンポーネントの最上位スコープで宣言(またはインポート)されたストア変数でのみ機能します。

$count の使用はマークアップ内に限定されません。イベントハンドラやリアクティブ宣言など、<script> のどこでも使用できます。

$ で始まる名前はストア値を参照していると見なされます。これは事実上の予約文字です。Svelte では $ プレフィックスを使った独自変数を宣言できません。