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 内のすべてのオブジェクト (および配列) は、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 ゲッター/セッターを使用してください。
わかりました。オブジェクトと配列は問題なく、Svelte によって自動的に処理されます。わかりました。
しかし、
はどうでしょうか
日付、URL、その他標準 JavaScript の組み込みオブジェクト? JavaScript の経験が豊富な方は、さらに高度なデータ型 (標準の組み込みオブジェクト) があることをご存じかもしれません。
Set オブジェクトを使用すると、プリミティブ値でもオブジェクト参照でも、任意の型の一意の値を保存できます。
Map オブジェクトはキーと値のペアを保持し、キーの元の挿入順序を記憶します。
これらを reactive $state で使用したい場合は、svelte/reactivity の対応する Svelte ラッパーを使用する必要があります
// 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:
を使用してオブジェクトと配列をそのまま使用できることがわかりました。
<!-- 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 を共有する (単純)
すでにご存知かもしれませんが、テキスト入力用のハンドラー関数を作成する必要はありません。 binding:value={myStateObj} を使用するだけで、状態を自動的に更新できます。
import { searchState } from './sharedState.svelte.js'; searchState = {text: "Hello world!"}; // don't do this!
複数のチェックボックス入力は、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 コンポーネント間で状態を共有する (ダミー用)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。