Svelte 5におけるProxyオブジェクトの活用

Svelte 5では$state以外でも広範囲にProxyオブジェクトを活用しています。

$stateによるリアクティビティ

$stateは内部でProxyを使用して、オブジェクトや配列への読み書きを監視します。

let user = $state({
  name: '太郎',
  age: 25
});

// Proxyにより、プロパティへのアクセスや変更が追跡される
user.age++; // 自動的にUIが更新される
typescript

ビルトインクラスのリアクティブ拡張

Svelte 5では、以下のネイティブクラスも$state()と組み合わせることで自動的にProxyでラップされます。

// Map
let myMap = $state(new Map());
myMap.set('key', 'value'); // Proxyによりリアクティブに

// Set
let mySet = $state(new Set(['A']));
mySet.add('B'); // 変更が自動追跡

// Date
let now = $state(new Date());
now.setHours(10); // UIが更新される

// URL
let url = $state(new URL('https://example.com'));
url.searchParams.set('query', 'svelte'); // 変更検知

// URLSearchParams
let params = $state(new URLSearchParams('a=1'));
params.set('b', '2'); // リアクティブに更新
typescript

$derivedと$effectの依存関係追跡

$derived$effectも内部的にProxyの仕組みを利用して、依存関係を自動追跡しています。

let count = $state(0);
let items = $state([1, 2, 3]);

// Proxyによって、countとitemsへのアクセスが追跡される
let total = $derived(() => {
  return count + items.length; // 両方の依存関係が自動検出
});

// effectも同様に依存関係を追跡
$effect(() => {
  console.log(`Count: ${count}, Items: ${items.length}`);
  // countまたはitemsが変更されると再実行
});
typescript

深いリアクティビティの実現

Proxyの再帰的な適用により、ネストされたオブジェクトも自動的にリアクティブになります。

let data = $state({
  user: {
    profile: {
      settings: {
        theme: 'dark'
      }
    }
  }
});

// 深くネストされたプロパティもProxyで追跡
data.user.profile.settings.theme = 'light'; // UIが更新される
typescript

配列メソッドの追跡

Svelte 5では、Proxyによって配列の破壊的メソッドも追跡可能になりました。

let items = $state([1, 2, 3]);

// これらすべてがProxyによって検知される
items.push(4);      // ✅ UI更新
items.pop();        // ✅ UI更新
items.splice(1, 1); // ✅ UI更新
items[0] = 10;      // ✅ UI更新
typescript

まとめ

Svelte 5のリアクティビティシステムは、Proxyを中核技術として採用しています。

機能Proxyの使用効果
$stateオブジェクト・配列の変更を自動追跡
ビルトインクラスMap/Set/Date等もリアクティブに
$derived依存関係の自動検出
$effect必要な時だけ副作用を実行
深いリアクティビティネストされた構造も自動追跡

これにより、Angular(RxJS)のような明示的な状態管理と比べて、より自然でシンプルなコードが書けるようになっています。特に、TypeScriptとの相性も良く、型推論も正確に動作するのが大きな利点です。

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