Skip to main content

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

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

App.svelte
const unsubscribe = count.subscribe((value) => {
	count_value = value;
});

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

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

App.svelte
<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 count_value;

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

	onDestroy(unsubscribe);
</script>

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

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

App.svelte
<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 count_value;

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

	onDestroy(unsubscribe);
</script>

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

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

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

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

Next: Readable stores

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
	import { count } from './stores.js';
	import Incrementer from './Incrementer.svelte';
	import Decrementer from './Decrementer.svelte';
	import Resetter from './Resetter.svelte';
 
	let count_value;
 
	count.subscribe((value) => {
		count_value = value;
	});
</script>
 
<h1>The count is {count_value}</h1>
 
<Incrementer />
<Decrementer />
<Resetter />
 
initialising