Web制作、Web開発の歩き方

デザイナー、Web制作者もできるSvelte入門

■第9話:Svelteの新しい状態管理、Runes

(最終更新日:2025.05.06)

Svelteのイメージ
この記事は7分で読めます!
(絵が小さい場合はスマホを横に)

「状態管理を分かりやすく」

Svelte5では、状態管理の仕組みが大きく見直され、新たに「Runes(ルーン)」と呼ばれる構文が導入された。 従来の$:によるリアクティブ宣言に代わり、関数ベースでより明示的かつ構造的な状態管理が可能になる。 本記事では、Runesを使って状態管理の基本から応用までを一気に紹介する。


1.Runesの基本:状態・派生・副作用

1.1 $state — 再代入可能な状態
$stateはリアクティブな状態を定義するためのRuneだ。 以前はletで文頭で定義するだけでリアクティブな状態に出来たが、Runesを用いる場合は、$stateを使って初期値と共に定義する。 以下のように定義する。count++ のように再代入すれば、自動的にUIも更新される。

$stateによるリアクティブの定義

1.2 $derived — 派生した値の自動更新
$derivedは、他の状態から導かれる値を定義するRuneだ。 下記のように定義すると、countの値が奇数の時にisEven()がfalse、偶数の時にisEven()がtrueを示すようになる。

$derivedによる派生した値の更新

1.3 $effect — 値の変化に応じた副作用処理
$effectは副作用の処理になる。countの値が変化した際にalertを出す。 下記の場合、countが5の倍数になった際にalertを表示する。

$effectによる副作用の反映

1.4 $props — 親コンポーネントから値を受け取る
$propsを用いると、親コンポーネントから値(プロパティ)を受け取ることができる。 以前は子コンポーネントでexport letを定義して受け取っていたので、 $propsを使うことで、よりプロパティを受け取っていることが明確になる。

$propsで親コンポーネントから値を受け取る

1.5 その他のRunes
上記の4つ以外にも、双方向に値を反映できるようになる$bindable、 自コンポーネントのルートDOM要素を取得する$host、ログを出力する$inspect、 子コンポーネントから親コンポーネントへイベントを通知する$dispatchなどがある。 取り合えず、ここまで覚えておけば、一通り作りたいものは作れるはずだ。


2.高度なRunes、コンポーネント間の連携

1.5、その他のRunesで紹介した少し高度なRunesについても解説しよう。

2.1 $props と $bindable
$propsは親コンポーネントから子コンポーネントへ値を受け渡す場合に使う。 そして、$bindableは双方向バインディングさせたい場合に使う。 これにより、子から親に値を渡すこともできるようになる。

$inspect — 状態の監視

2.2 $inspectによるログ出力
$inspectを使うと、状態をconsoleで出力することができる。 使い方は以下の通りである。単純にconsole.logで出力した結果が出る。

$inspectで状態をconsole出力する

2.3 $host — DOM要素の直接操作
$hostを使うと、DOM要素を直接呼び出すことができる。 以下のように、対象のDOMのstyleを変更することができる。

$hostでDOM要素を直接操作

3.実践:カウンターアプリでRunesを体感

実際のカウンターアプリで、その様子を見てみよう。 まずは、$stateと$derivedは、他の状態から導かれる値を定義するRuneだ。 こちらは最初に説明した$stateと$derivedを用いた例になる。 count変数の変化によって、表示がcountの値と「偶数」「奇数」に変化する。

$stateと$derivedによるカウンター

これは、下記のような非常に単純なコードになる。$stateを用いてcount変数をリアクティブな状態にして、 $derivedを用いて2で割り切れるときに偶数、そうでないときに奇数と表示するようにしている。 countはincrement関数によって、ボタンを押したときに1ずつ増加し、増加した時の変化が表示に反映されるようにしている。

$stateと$derivedのリアクティブなコード

次に$bindableを用いた例を示す。$bindableは子コンポーネントの変化を親コンポーネントに反映させるときに使う。 加えて下記では、子コンポーネントの変化を子コンポーネント自体にも反映している。 inputで入力した文字が各々のコンポーネントの表示に反映されている。

$bindableによる双方向バインディング

実際のコードは下記のようになる。子コンポーネントは$propsで親からの値を受け取っている。 これを$bindableで受けることで、子コンポーネントのinputの入力値(テキスト)を変化させると、 子コンポーネントのvalue、親コンポーネントのvalue(=message)、両方を同時に変化させることができる。

子コンポーネント(上)と親コンポーネント(下)

最後に$hostの例を説明する。 こちらはDOM要素を直接呼ぶもので、このようにDOM要素のstyleを変更すると、 そのコンポーネントのstyleを変更することができる。

$hostによるstyleの変更

このコンポーネントはdecrementボタンとincrementボタンからだけでなるので、 そのコンポーネントの周りだけが青くなっているのが分かると思う。

$hostによるstyleの反映

4.注意点

Runeは関数であるため、必ず()をつけて呼び出す必要がある。 そして、$stateを使わない再代入はリアクティブにならず、ただの変数になる。 $hostに関しても必ず()を付けよう。「let el = $host」ではなく「let el = $host()」と各必要がある。

5.まとめと今後の展望

RunesによってSvelteの状態管理はより構造的で直感的になった。 副作用の分離や状態の可視性向上により、大規模開発にも適したアーキテクチャが実現可能になる。 Svelte5は昨年の10月に安定版がリリースされ、Runesの機能を如何なく発揮できる。 ReactやVueに並ぶフロントエンドの選択肢として本格的に導入できるフェーズに来ている。 新しいプロジェクトがある際には、ぜひSvelteを使ってみよう。 モダンフロントを知らないメンバーでも、比較的早く使いこなせるはずだ。

▼参考図書、サイト

   Introducing runes SVELTE公式サイト
   Svelte Tutorial SVELTE公式サイト