$state.raw() vs $state() の違いと使い分け

Svelte 5 における $state()$state.raw() は、どちらもリアクティブな状態管理を行うための仕組みですが、内部動作やユースケースに明確な違いがあります。

このドキュメントでは、それぞれの違いと使い分けのポイントをわかりやすく解説します。

state() とは?

$state() は、Svelte のリアクティブステートの基本構文です。これは、内部で Proxy を用いて読み書きを監視することにより、リアクティブなUI更新を実現します。

基本的な使い方

コンポーネントのスクリプト部分では、次のように記述します:

// $stateの初期化
let counter = $state(0);

function increment() {
  counter = counter + 1; // 自動的に変更が検知される
}
typescript

テンプレート部分では通常のJavaScript変数として使用できます:

<p>Count: {counter}</p>
<button onclick={increment}>+1</button>
html
  • 直感的に書ける
  • 変数の更新が自動的に UI に反映される
  • count++array.push() などの操作も検知される(Svelte 5では構造化された操作も追跡可能)

state.raw() とは?

$state.raw() は、Proxy を経由せず、生の状態オブジェクトを手動で管理するための低レベルAPIです。リアクティブな更新を行うためには、明示的に $get()$set() を使う必要があります。

基本的な使い方

// $state.rawの初期化
let counter = $state.raw(0);

function increment() {
  $set(counter, $get(counter) + 1);
  // 手動で更新を通知する必要がある
}
typescript

テンプレート部分では $get() を使用して値を取得します:

<p>Count: {$get(counter)}</p>
<button onclick={increment}>+1</button>
html
  • count は Proxy ではなくプレーンな値参照
  • $get() で取得し、$set() で更新する必要がある
  • より 厳密な制御やトレース を行いたい場合に使用

違いまとめ

項目$state()$state.raw()
リアクティブ自動(Proxy)手動($get / $set
直感的な書き方可能不可(明示的な操作が必要)
適用例通常のフォームや状態管理Map/Set、外部ライブラリ連携、デバッグ用途など
内部処理Proxy による追跡生値への直接アクセス

いつ state.raw() を使う?

以下のような場合に有効です。

  • Map, Set, Date, File などの 特殊なネイティブ型 を扱うとき
  • 外部ライブラリと状態を連携する際に、変更検知の細かい制御をしたいとき
  • 自作のステート更新処理で、どのタイミングで再描画させるかを明示的に制御したいとき
  • デバッグ目的で状態の取得・更新をログしたいとき

図解:状態管理の構造の違い

使用例:Mapなどの特殊型

stateでMapを使う場合の問題

// ❌ $stateでMapを使うと更新がUIに反映されないことがある
let myMap = $state(new Map());
myMap.set('key', 'value'); // 再描画されない可能性
typescript

state.rawを使った解決策

// ✅ $state.rawを使う
let myMap = $state.raw(new Map());

function updateMap() {
  const map = $get(myMap);
  map.set('key', 'updated');
  $set(myMap, map); // 明示的に通知
}
typescript

外部ライブラリと連携する場合

// コンポーネントのスクリプト部分
let chartData = $state.raw([]);

function fetchDataFromLibrary() {
  const data = externalLibrary.getData(); // 外部で生成
  $set(chartData, data); // 手動で設定
}
typescript

テンプレート部分:

<ChartComponent data={$get(chartData)} />
html

結論

通常は $state() を使い、必要な場面でだけ $state.raw() を使うのがベストです。

高度な制御が必要な場面を除いては、$state() で完結するコードの方が簡潔かつ安全です。

Last update at: 2025/08/14 07:39:43