Svelte 5のRunesをSvelte 4と並べて比較
Svelte 5のRunes
Svelte 5のRunes:$state、$derived、$effect、$props | We.Inc
Svelte 5の全ルーンと、それが置き換えるSvelte 4のコードを比較。$state、$derived、$effect、$props、$bindable、新しいイベントとスニペットの構文。コピーして使える例付き。
ルーン(Runes)は、Svelte 5がリアクティビティに使うコンパイラーのキーワードです。$stateはリアクティブな変数を宣言し、$derivedは他の状態から値を計算し、$effectはページの更新後にコードを実行し、$propsはコンポーネントのpropsを読み取り、$bindableは親がバインドできるpropsを示します。これらはSvelte 4のリアクティブなlet、$:ラベル、export letを置き換えます。
Svelte 4の構文とそれを置き換えるルーン
- リアクティブな変数
- let count = 0
- let count = $state(0)
- 計算された値
- $: doubled = count * 2
- let doubled = $derived(count * 2)
- 副作用
- $: console.log(count)
- $effect(() => console.log(count))
- Props
- export let name
- let { name } = $props()
- バインド可能なprops
- export let value
- let { value = $bindable() } = $props()
- イベントハンドラー
- on:click={fn}
- onclick={fn}
- コンポーネントのイベント
- createEventDispatcher
- コールバックprops
- スロット
- <slot />
- {#snippet}と{@render}
ルーンを選ぶと、Svelte 4のコンポーネントとそれをSvelte 5で書き直したものが表示されます。各ペアは同じ動作をするので、1ファイルずつ移行し、結果を確認しながら進められます。
- ボタンからルーンまたは構文の変更点を選びます。
- 左のSvelte 4のコードと右のSvelte 5のコードを比べます。
- つまずきやすいルールについての注記を読みます。
- Svelte 5版をコンポーネントにコピーします。
- 計算で求められるものには$derivedを使いましょう。$effectは、ドキュメントのタイトル、キャンバス要素、サードパーティのウィジェットなど、Svelteの外部とやり取りするときのために取っておきます。
- $effectはサーバーレンダリング中には実行されないため、windowやdocumentに触れるコードを置いても安全です。
- 丸ごと置き換えるだけの大きな配列には$state.rawを使いましょう。深いプロキシを省略し、再代入のみが可能になります。
- プロキシではなくプレーンなオブジェクトを想定するライブラリには、$state.snapshot(value)を渡しましょう。
- ルーンは.svelte.jsや.svelte.tsファイルでも使えるため、リアクティブなロジックをコンポーネントの外で共有できます。
よくある質問
Svelte 5のためにアプリ全体を書き直す必要がありますか?
必要ありません。Svelte 5は引き続きSvelte 4の構文をサポートしており、旧来のコンポーネントとルーンを使ったコンポーネントを同じアプリに置いて互いに使えるため、ファイルを1つずつ変換できます。
$effectが再実行されないのはなぜですか?
Svelteが追跡するのは、エフェクト内で同期的に読み取られた状態だけです。awaitの後やsetTimeoutのコールバック内で読み取った値は依存関係にならないため、変更しても何も起きません。
$derivedの値を変更できますか?
Svelte 5.25以降では、constで宣言していない限り、派生値を一時的に再代入できます。楽観的更新に役立ちます。依存関係が変わると再計算されます。それより前のバージョンでは、派生値は読み取り専用です。
createEventDispatcherは何に置き換えられましたか?
コールバックpropsです。子はonsaveのような関数を$propsで受け取って呼び出し、親は他の属性と同じようにハンドラー関数を渡すだけです。
フォームのフィールドに一意のidを付けるには?
Svelte 5.20で追加された$props.id()を呼び出します。コンポーネントのインスタンスごとに一意で、サーバーとブラウザーで一致するidを返すため、forやaria-labelledbyに安全に使えます。
$stateはデフォルトで深いリアクティブ
- 配列やプレーンなオブジェクトを$stateで囲むと、深くリアクティブなプロキシが得られます。配列への要素の追加やネストしたプロパティの設定を行うと、それを読み取っているページの部分だけが更新され、値全体を再代入する必要はありません。
- クラスのフィールドも状態にできます。クラス内で$stateを使ってフィールドを宣言すると、コンパイラーがゲッターとセッターのペアに変換します。
$derivedは純粋に保つ
- $derived内の式は計算だけを行うべきです。Svelteはその中でのcount++のような状態変更を拒否します。長いロジックには$derived.byを使います。関数を受け取り、その戻り値が派生値になります。
- 派生値は遅延評価されます。依存関係が変わるとSvelteは古いものとしてマークし、次に読み取られたときに再計算します。結果が同じなら、その先の処理は省略されます。
$effectのタイミングとクリーンアップ
- エフェクトはコンポーネントのマウント後に実行され、依存関係が変わるとDOMの更新後に再実行されます。エフェクトから関数を返すと、次の実行前やコンポーネントの破棄時にタイマーやリスナーをクリーンアップできます。
- チャットログを最下部までスクロールしたままにするなど、DOMが変わる前に何かを測定や調整する必要がある場合は、代わりに$effect.preを使います。
コンポーネント間で状態を共有する
.svelte.jsファイルのリアクティブなストア
再代入される$state変数は直接エクスポートできないため、オブジェクトをエクスポートし、そのプロパティを変更します。
$state
ルーンモードでは、ただのletはもうリアクティブではありません。初期値を$stateで囲み、通常の変数と同じように更新します。
$derived
$:ラベルは2つの役割を担っていました。計算は$derivedになり、元になる値が変わるとSvelteが自動的に再計算します。
$effect
$:による副作用は$effectに移ります。DOMの更新後にブラウザーで実行され、戻り値がクリーンアップになります。
$props
すべてのpropsは1つの分割代入の文で受け取ります。デフォルト値、名前の変更、残りのpropsは通常のJavaScriptの構文で書きます。
$bindable
propsを$bindableでマークすると、親がbind:を使えるようになります。親のコードは変わりません。
イベント
on:clickはonclick属性になり、カスタムイベントはcreateEventDispatcherの代わりにコールバックpropsになります。
スニペット
childrenスニペットがデフォルトのスロットを置き換え、{@render}で配置します。?.により、子要素が渡されなかったときは描画を省略します。
Svelte 4のコードとSvelte 5での書き直し
ルーンを選択
Svelte 4
Svelte 5(ルーン使用)
Svelte 4をコピー
Svelte 5をコピー
例 {n} / {v}
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る