ホームページ > ウェブフロントエンド > jsチュートリアル > Svelte コンポーネント間で状態を共有する (ダミー用)

Svelte コンポーネント間で状態を共有する (ダミー用)

Mary-Kate Olsen
リリース: 2025-01-03 17:18:43
オリジナル
435 人が閲覧しました

Svelte Share state between components (for dummies)

Svelte 5 で新しい $state を見るとすぐに、次のことを実行したくなるかもしれません:

// sharedState.svelte.js
export const searchState = $state(""); // This won't work!
ログイン後にコピー
ログイン後にコピー
<!-- App.svelte -->
<script>
import { searchState } from './sharedState.svelte.js'

function handleClick(){
    // This won't work!
    searchState = "bicycles";
}
</script

<button onclick={handleClick}>Search for bicycles</button>
ログイン後にコピー
ログイン後にコピー

これは機能しません - その理由は次のとおりです:

あなたは Svelte 5 の最も複雑な部分に遭遇しています。反応性がどのように機能し、コンパイラーがそれをどのように隠しているか。

数値や文字列などの単一の値をエクスポートする場合、JavaScript にはそれを追跡する方法がないため、Svelte が反応性を維持するメカニズムはありません。

これを簡単な言葉で説明してくれたマット・サイモンに感謝します?私が学んだことは次のとおりです:

$state は文字列ではなくオブジェクトと配列で使用してください。

文字列を直接使用することはできませんが、$state 内のすべてのオブジェクト (および配列) は、Svelte 5 によって自動的にプロキシされたすべての値を取得します。文字列値をオブジェクトにラップすることは機能します。

// sharedState.svelte.js
// ❌ export const searchState = $state("");
export const searchState = $state({ text : "" });
ログイン後にコピー
ログイン後にコピー

これは、.text のゲッターとセッターを備えた Svelte 状態オブジェクトに変わりました。任意のプロパティ名を選択することも、複数のプロパティを選択することもできます。

この $state オブジェクトをインポートし、次に .text = を記述すると、Svelte セッターを使用して状態を更新します。

// App.svelte

import { searchState } from './sharedState.svelte.js'

function handleClick(){
    // uses the automatically created setter
    searchState.text = "bicycles";
}

<button onclick={handleClick}>Search for bicycles</button>
ログイン後にコピー
ログイン後にコピー

簡単なデモ (REPL)): コンポーネント間で $state を共有する (単純)

Svelte は、これらのオブジェクトをプロキシする方法について非常に賢明です。 Svelte がプッシュ メソッドもプロキシしているため、myList.push('foo') は配列に対しても機能します。

// data.svelte.js
export const myList = $state([]);
ログイン後にコピー
ログイン後にコピー

注意: オブジェクト/配列を直接再割り当てしないでください。

オブジェクト (配列を含む) を使用する場合、それらはそれ自体が状態ではありません。それを理解することが重要です。

これを行うと、反応性が失われます!

import { searchState } from './sharedState.svelte.js';
searchState = {text: "Hello world!"}; // don't do this!
ログイン後にコピー
ログイン後にコピー

Svelte がこれを処理する方法はありません。 searchState.text = 'new value' を介して、常に自動 Svelte ゲッター/セッターを使用してください。

上級: SvelteSet、SvelteMap、SvelteDate などを使用します。

わかりました。オブジェクトと配列は問題なく、Svelte によって自動的に処理されます。わかりました。

しかし、
はどうでしょうか 日付、URL、その他標準 JavaScript の組み込みオブジェクト? JavaScript の経験が豊富な方は、さらに高度なデータ型 (標準の組み込みオブジェクト) があることをご存じかもしれません。

  • Set オブジェクトを使用すると、プリミティブ値でもオブジェクト参照でも、任意の型の一意の値を保存できます。

  • Map オブジェクトはキーと値のペアを保持し、キーの元の挿入順序を記憶します。

これらを reactive $state で使用したい場合は、svelte/reactivity の対応する Svelte ラッパーを使用する必要があります

  • メディアクエリ
  • SvelteDate
  • SvelteMap
  • スベルトセット
  • SvelteURL
  • SvelteURLSearchParams
// sharedState.svelte.js
export const searchState = $state(""); // This won't work!
ログイン後にコピー
ログイン後にコピー

SvelteSet クラスと SvelteMap クラスが (オブジェクトや配列のように自動的に書き換えるのではなく) 別々に存在する理由は、考えられるすべてのオブジェクトをプロキシすることはできないため、どこかで線を引きたかったためです。技術的な詳細については、https://github.com/sveltejs/svelte/issues/10263 を参照してください。

上級: クラスを使用する

状態オブジェクトを定義するには複数のオプションがあり、カスタム メソッドのクラスを使用することもできます: https://joyofcode.xyz/how-to-share-state-in-svelte-5#using-classes-for-反応状態

コンポーネント間で状態を共有する ($state と $derived)

コンポーネント内で状態をインポート (および更新) する方法がわかり、$state:
を使用してオブジェクトと配列をそのまま使用できることがわかりました。

<!-- App.svelte -->
<script>
import { searchState } from './sharedState.svelte.js'

function handleClick(){
    // This won't work!
    searchState = "bicycles";
}
</script

<button onclick={handleClick}>Search for bicycles</button>
ログイン後にコピー
ログイン後にコピー

$props を使用してプロパティによる参照として $state オブジェクトを渡すこともできます。

// sharedState.svelte.js
// ❌ export const searchState = $state("");
export const searchState = $state({ text : "" });
ログイン後にコピー
ログイン後にコピー
// App.svelte

import { searchState } from './sharedState.svelte.js'

function handleClick(){
    // uses the automatically created setter
    searchState.text = "bicycles";
}

<button onclick={handleClick}>Search for bicycles</button>
ログイン後にコピー
ログイン後にコピー

しかし、コンポーネント内にいるときにアプリ内のどこかで状態が変化したことをどうやって知るのでしょうか?これが $derived と $derived.by の目的です:

// data.svelte.js
export const myList = $state([]);
ログイン後にコピー
ログイン後にコピー

簡単なデモ (REPL)): コンポーネント間で $state を共有する (単純)

bind:value での使用法

すでにご存知かもしれませんが、テキスト入力用のハンドラー関数を作成する必要はありません。 binding:value={myStateObj} を使用するだけで、状態を自動的に更新できます。

import { searchState } from './sharedState.svelte.js';
searchState = {text: "Hello world!"}; // don't do this!
ログイン後にコピー
ログイン後にコピー

bind:group での使用法?

複数のチェックボックス入力は、bind-group={stateObj} を介して Svelte でも処理できますが、$state でそれを正しく使用する方法については、まだ未解決の議論があります。

良いニュース: これを行うには複数の方法があります。以下を参照してください。

高度なデモ: 製品データの検索とフィルタリング

1 つの方法は、onchange イベント を使用することです。そしてハンドラー関数内の状態を更新します。

簡単なデモ (REPL): チェックボックス グループ コンポーネントと v5 $state & $derived を使用した検索とフィルター

完全な SvelteKit サンプル (WIP): https://github.com/mandrasch/austrian-web-dev-companies

さらにフィードバックを得るために Reddit ディスカッションも開始しました:
Svelte v5 ($state) でチェックボックスを検索およびフィルターする最も簡単な方法は何ですか?

フィードバックをここで受け取るか、ここでコメントとして受け取っていただければ幸いです。 ?

その他のリソース

  • Svelte 5 で状態を共有するさまざまな方法 - コードの楽しみ
  • Svelte 5、Sveltekit 2、Tailwind、Upstash (2024) を使用してフィルタリング システムを構築しましょう - Lawal Adebola
  • Svelte 5 - グローバル $state (ストアを $state ルーンに変換) - Svelte Mastery

マット・サイモンに感謝します!

以上がSvelte コンポーネント間で状態を共有する (ダミー用)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート