Svelteの読み取り可能および書き込み可能なストアの使用を開始する
ReduxまたはVuexに精通している場合、Svelteストアは状態管理のための同様の機能を提供します。 アプリが複雑になると、コンポーネント間でデータを中継することが難しくなります。 グローバルデータストアに移動することをお勧めします。 ここでは、Svelteが提供する2つのストアオプション、書き込み可能ストアと読み取り可能ストアについて説明します。
書き込み可能なストア
先に進んで、Svelteプロジェクトにグローバル状態管理ファイルを作成しましょう。それをstore.js
と呼び、writable
関数をインポートしましょう。
import { writable } from "svelte/store";
let counter = writable(1);
export {counter}
書き込み可能なストアであるcounter
という変数を作成しました。 counter
には、次の自明のメソッドがあります。
set
update
Nested.svelte
というカスタムコンポーネントを作成し、作成したcounter
ストアを使用してみましょう。
<script>
import { counter } from "./store.js";
</script>
<div>
counter value: {$counter}
</div>
これは名前付きインポートであるため、使用中は変数の前に$
を付けることに注意してください。
コンポーネントをApp.svelte
ファイルにインポートしてまとめ、counter
変数を記述して、ネストされたコンポーネント間の反応性を観察するメソッドを作成しましょう。
<script>
import Nested from "./Nested.svelte";
import { counter } from "./store.js";
function incrementCounter() {
counter.update(n => n + 1);
}
</script>
<div>
<button on:click={incrementCounter}>Update</button>
<Nested />
</div>
counter
は、update
メソッドを使用します。このメソッドは、パラメーターが書き込み可能ストアの現在の値であり、変更された値を返す関数を取ります。 このアプリを実行すると、ボタンをクリックすると、Nested
コンポーネント内の値が更新されるのを確認できるはずです。
その間に、reset
ボタンをApp.svelte
に追加してみましょう。
function resetCounter() {
counter.set(1);
}
<button on:click={resetCounter}>Reset</button>
resetCounter
は、書き込み可能なストアのset
メソッドを使用します。
現在、writable
関数は、これも関数である2番目の引数もサポートしています。 その関数のシグネチャは次のとおりです。
writable(value: any, (set: (value: any) => void) => () => void)
この関数は、最初のサブスクライバーが作成されたときに起動され、変数への最後のサブスクリプションが破棄されたときに起動される別の関数を返します。 それが実際に動いているのを見てみましょう。
store.js
で、書き込み可能な関数に2番目の引数を追加します。
let counter = writable(1, () => {
console.log("First subscriber added!");
return () => {
console.log("Last subscriber deleted :(");
};
});
これをテストするために、Nested
コンポーネントをマウントおよびアンマウントして、App.svelte
で動作を観察します。
<script>
// ...
let flag = false;
function toggleMount() {
flag = !flag;
}
</script>
<!-- ... -->
<button on:click={toggleMount}>Mount/Unmount</button>
{#if flag}
<Nested />
{/if}
</div>
読みやすい店
Svelteはreadable
関数も提供します。これにより、他のコンポーネントから値を更新できない読み取り可能なストアを作成できます。 値はストア内からset
にする必要があります。 これを試して、store.js
を変更してみましょう-
import { readable } from "svelte/store";
let initialVal = Math.floor(Math.random()*100);
let counter = readable(initialVal, (set) => {
let incrementCounter = setInterval( () => {
let newVal = Math.floor(Math.random()*100);
set(newVal);
}, 1000);
return () => {
clearInterval(incrementCounter);
};
});
export {counter}
ここで、readable
カウンターは、最初の引数として渡されるinitialVal
で設定されます。 2番目の引数は書き込み可能なストアの場合と同じですが、これがないとcounter
値にアクセスしてリセットする方法が他にないため、今回は必須パラメーターです。
この例では、0〜100の乱数を生成し、set
メソッドを使用してこれをcounter
に割り当てます。 update
は使用できません。 これは単純なデモですが、実際のアプリでは、読み取り可能なストアは2番目の引数を使用してAPI呼び出しを行い、一部のロジックに基づいてset
値を指定できます。 これにより、このストアにサブスクライブされているコンポーネントがレンダリングされます。
ご覧のとおり、Svelteのwritable
ストアとreadable
ストアを使用することで、基本的な形式のグローバル状態管理を非常に簡単に実現できます。 ✨