Svelte入門:リファレンス $app/stores -Vol.1-

スポンサーリンク
Svelte入門:リファレンス $app/stores -Vol.1- 用語解説
Svelte入門:リファレンス $app/stores -Vol.1-
この記事は約13分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、SvelteKitのリファレンスについて解説しています。

スポンサーリンク

背景

SvelteKitのリファレンスについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。

$app/stores

このモジュールには、$app/state からのエクスポートに相当するストアベースの機能が含まれています。SvelteKit 2.12 以降を使用している場合は、代わりに $app/state モジュールを使用してください。

import { getStores, navigating, page, updated } from '$app/stores';

$app/stores モジュールは SvelteKit の以前のバージョンで使用されていたモジュールで、現在のページ情報やナビゲーション状態にアクセスするための Svelte ストアを提供します。SvelteKit 2.12 以降では、代わりに $app/state モジュールを使用することが推奨されています。

このモジュールには以下の主要なエクスポートが含まれています:

  1. getStorespagenavigatingupdated ストアを含むオブジェクトを返す関数です。通常は直接インポートした方が便利ですが、関数内で使用する場合など、特定のケースで役立ちます。
  2. page – 現在のページに関する情報(URL、パラメータ、データなど)を含む読み取り専用ストアです。
  3. navigating – 進行中のナビゲーションに関する情報を含むストア、またはナビゲーションが発生していない場合は null です。
  4. updated – アプリケーションの新しいバージョンが利用可能かどうかを示すストアです。

使用例

<script>
  import { page, navigating, updated } from '$app/stores';
  
  // 購読構文を使用した値の取得
  $: currentPath = $page.url.pathname;
  $: routeParams = $page.params;
  $: isNavigating = $navigating !== null;
  $: hasUpdate = $updated.current;
  
  // ページデータへのアクセス
  $: pageData = $page.data;
  
  // エラーの処理
  $: hasError = $page.error !== null;
  
  // フォームデータへのアクセス
  $: formData = $page.form;
  
  // 関数内でストアを使用
  function handleClick() {
    if ($navigating) {
      // ナビゲーション中は何もしない
      return;
    }
    
    console.log('現在のページ:', $page.url.pathname);
    // 他の処理...
  }
</script>

<!-- 現在のページ情報の表示 -->
<header>
  <h1>現在のページ: {currentPath}</h1>
  {#if Object.keys(routeParams).length > 0}
    <h2>パラメータ: {JSON.stringify(routeParams)}</h2>
  {/if}
</header>

<!-- ナビゲーション中のローディングインジケータ -->
{#if isNavigating}
  <div class="loading">
    ページ読み込み中...
    {#if $navigating.to}
      {$navigating.from.url.pathname} から {$navigating.to.url.pathname} へ移動しています
    {/if}
  </div>
{/if}

<!-- アップデート通知 -->
{#if hasUpdate}
  <div class="update-notice">
    <p>新しいバージョンが利用可能です</p>
    <button on:click={() => location.reload()}>
      更新する
    </button>
  </div>
{/if}

<!-- エラー表示 -->
{#if hasError}
  <div class="error">
    <h2>エラーが発生しました</h2>
    <p>{$page.error.message}</p>
  </div>
{/if}

<style>
  .loading {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 1rem;
    text-align: center;
    z-index: 1000;
  }
  
  .update-notice {
    position: fixed;
    bottom: 1rem;
    right: 1rem;
    background: #4caf50;
    color: white;
    padding: 1rem;
    border-radius: 4px;
    display: flex;
    align-items: center;
    gap: 1rem;
  }
  
  .error {
    border: 2px solid red;
    padding: 1rem;
    margin: 1rem 0;
    background: #fff0f0;
  }
</style>

getStores の使用例

<script>
  import { getStores } from '$app/stores';
  import { onMount } from 'svelte';
  
  let currentPage;
  
  onMount(() => {
    // コンポーネントのマウント後にストアにアクセス
    const { page } = getStores();
    
    // ストア購読
    const unsubscribe = page.subscribe(value => {
      currentPage = value;
      console.log('ページが更新されました:', value.url.pathname);
    });
    
    // クリーンアップ
    return unsubscribe;
  });
  
  // または関数内でストアを使用
  function logCurrentPage() {
    const { page } = getStores();
    
    // 一度だけ値を取得(購読せず)
    const value = page.get();
    console.log('現在のページ(関数内):', value.url.pathname);
  }
</script>

<button on:click={logCurrentPage}>現在のページを記録</button>

注意点

  1. SvelteKit 2.12 以降では非推奨 – 新しいプロジェクトでは、代わりに $app/state モジュールを使用してください。
  2. Svelte ストア – これらは Svelte のストアなので、値にアクセスするには $ 記号を使用する必要があります(例: $page)。
  3. サーバーサイドでの制限 – サーバーサイドでは、これらのストアはレンダリング中(コンポーネント内)でのみアクセス可能で、load 関数などではアクセスできません。
  4. リアクティビティ – ストアの値は変更に応じて自動的に更新され、それに依存するすべての変数や UI 要素も更新されます。

SvelteKit 2.12 以前のバージョンを使用している場合、このモジュールは、アプリケーション全体で現在のページやナビゲーション状態に関する情報にアクセスするための主要な方法です。

getStores

function getStores(): {
	page: typeof page;
	navigating: typeof navigating;
	updated: typeof updated;
};

解説

getStores は SvelteKit の $app/stores モジュールが提供する関数で、以下のような特徴があります:

  1. ストアの取得pagenavigatingupdated の3つの Svelte ストアを含むオブジェクトを返します。
  2. 戻り値 – 以下のプロパティを持つオブジェクトを返します:
    • page – 現在のページに関する情報を含むストア
    • navigating – 進行中のナビゲーションに関する情報を含むストア
    • updated – アプリケーションの更新状態を含むストア
  3. 使用シナリオ – 主に以下のような状況で使用されます:
    • コンポーネント初期化後(onMount 内など)にストアにアクセスする必要がある場合
    • 通常のスコープ外(関数内など)でストアにアクセスする必要がある場合
    • ストアをまとめて取得したい場合
  4. 代替手段 – 多くの場合、個々のストアを直接インポートする方が簡潔です(例:import { page } from '$app/stores';)。

使用例

<script>
  import { getStores } from '$app/stores';
  import { onMount } from 'svelte';
  
  let currentPath;
  let isNavigating = false;
  
  onMount(() => {
    // すべてのストアを一度に取得
    const stores = getStores();
    const { page, navigating, updated } = stores;
    
    // page ストアを購読
    const unsubPage = page.subscribe(value => {
      currentPath = value.url.pathname;
      console.log('現在のパス:', currentPath);
    });
    
    // navigating ストアを購読
    const unsubNav = navigating.subscribe(value => {
      isNavigating = value !== null;
      if (isNavigating) {
        console.log('ナビゲーション中:', value.from.url.pathname, '->', value.to.url.pathname);
      }
    });
    
    // アンマウント時にクリーンアップ
    return () => {
      unsubPage();
      unsubNav();
    };
  });
  
  // 任意のスコープでストアを使用する関数
  function logPageInfo() {
    const { page } = getStores();
    // ストアから現在の値を取得(購読せず一度だけ取得)
    const pageValue = page.get();
    
    console.log('==== ページ情報 ====');
    console.log('URL:', pageValue.url.toString());
    console.log('パラメータ:', pageValue.params);
    console.log('ルート:', pageValue.route.id);
    console.log('データ:', pageValue.data);
  }
</script>

<div>
  {#if currentPath}
    <p>現在のパス: {currentPath}</p>
  {/if}
  
  {#if isNavigating}
    <p>ページ読み込み中...</p>
  {/if}
  
  <button on:click={logPageInfo}>
    ページ情報を記録
  </button>
</div>

使用例:ユーティリティ関数内でのストアの使用

// utils.js
import { getStores } from '$app/stores';

// 現在のURLパラメータを取得するユーティリティ関数
export function getCurrentParams() {
  const { page } = getStores();
  return page.get().params;
}

// 現在のルートが特定のパターンにマッチするかチェックする関数
export function isRoute(pattern) {
  const { page } = getStores();
  const path = page.get().url.pathname;
  
  if (typeof pattern === 'string') {
    return path === pattern;
  } else if (pattern instanceof RegExp) {
    return pattern.test(path);
  }
  
  return false;
}

// ナビゲーション中かどうかをチェックする関数
export function isNavigating() {
  const { navigating } = getStores();
  return navigating.get() !== null;
}

注意点

  1. パフォーマンス – ストアの購読と解除は適切に行う必要があります。不要になったら必ず購読を解除してメモリリークを防ぎましょう。
  2. サーバーサイドの制限 – サーバーサイドではコンポーネントのレンダリング中にのみストアが利用可能で、それ以外のコンテキスト(load 関数内など)では使用できません。
  3. 代替アプローチ – SvelteKit 2.12 以降では、この関数の代わりに $app/state からエクスポートされる値を直接使用することが推奨されています。
  4. ストアの使用法 – 値を取得するには .get() を使用するか(一回だけ取得)、.subscribe() で変更を監視し続けることができます。

getStores は、特に動的なコンポーネント内や、通常のスコープ外でこれらのストアにアクセスする必要がある場合に便利な関数です。ただし、ほとんどの一般的なユースケースでは、個々のストアを直接インポートする方が簡単です。

おわりに

今日は、 SvelteKitのリファレンスについて解説しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました