コンテキスト
ほとんどの状態は、コンポーネントが存続する限り存続するコンポーネントレベルの状態です。しかし、セクション全体またはアプリ全体の状態もあり、これも何らかの形で処理する必要があります。
それを実行する最も簡単な方法は、グローバル状態を作成してインポートすることです。
export const const myGlobalState: {
user: {};
}
myGlobalState = function $state<{
user: {};
}>(initial: {
user: {};
}): {
user: {};
} (+1 overload)
namespace $state
Declares reactive state.
Example:
let count = $state(0);
$state({
user: {}
user: {
/* ... */
}
/* ... */
});
<script>
import { myGlobalState } from './state.svelte';
// ...
</script>
しかし、これにはいくつかの欠点があります。
- グローバル状態がクライアントサイドでのみ使用される場合(たとえば、サーバー上でコンポーネントをレンダリングしないシングルページアプリケーションを構築する場合)にのみ安全に機能します。状態がサーバーで管理および更新される場合、セッションやユーザー間で共有される可能性があり、バグが発生する可能性があります。
- 実際にはアプリの一部のみに使用されるべき状態が、グローバルであるという誤った印象を与える可能性があります。
これらの欠点を解決するために、Svelteはこれらの問題を軽減するいくつかのcontext
プリミティブを提供します。
コンテキストの設定と取得
現在のコンポーネントに任意のオブジェクトを関連付けるには、setContext
を使用します。
<script>
import { setContext } from 'svelte';
setContext('key', value);
</script>
コンテキストは、その後、getContext
を使用してコンポーネントの子(スロットされたコンテンツを含む)で使用できます。
<script>
import { getContext } from 'svelte';
const value = getContext('key');
</script>
setContext
とgetContext
は上記の課題を解決します。
- 状態はグローバルではなく、コンポーネントにスコープされます。そのため、サーバーでコンポーネントを安全にレンダリングし、状態を漏洩させることはありません。
- 状態はグローバルではなく、特定のコンポーネントツリーにスコープされているため、アプリの他の部分で使用できないことが明確になります。
setContext
/getContext
は、コンポーネントの初期化中に呼び出す必要があります。
コンテキストは本質的にリアクティブではありません。コンテキストでリアクティブな値が必要な場合は、プロパティがリアクティブになる$state
オブジェクトをコンテキストに渡すことができます。
<script>
import { setContext } from 'svelte';
let value = $state({ count: 0 });
setContext('counter', value);
</script>
<button onclick={() => value.count++}>increment</button>
<script>
import { getContext } from 'svelte';
const value = getContext('counter');
</script>
<p>Count is {value.count}</p>
親コンポーネントのコンテキストに特定のkey
が設定されているかどうかを確認するには、hasContext
を使用します。
<script>
import { hasContext } from 'svelte';
if (hasContext('key')) {
// do something
}
</script>
最も近い親コンポーネントに属するコンテキストマップ全体をgetAllContexts
を使用して取得することもできます。これは、たとえば、プログラムでコンポーネントを作成し、既存のコンテキストを渡す場合に役立ちます。
<script>
import { getAllContexts } from 'svelte';
const contexts = getAllContexts();
</script>
コンテキスト操作のカプセル化
上記の方法は、使用方法について非常に無意見です。アプリの規模が大きくなると、コンテキストの設定と取得を関数にカプセル化し、適切に型指定することが価値があります。
import { function getContext<T>(key: any): T
Retrieves the context that belongs to the closest parent component with the specified key
.
Must be called during component initialisation.
getContext, function setContext<T>(key: any, context: T): T
Associates an arbitrary context
object with the current component and the specified key
and returns that object. The context is then available to children of the component
(including slotted content) with getContext
.
Like lifecycle functions, this must be called during component initialisation.
setContext } from 'svelte';
let let userKey: symbol
userKey = var Symbol: SymbolConstructor
(description?: string | number) => symbol
Returns a new unique Symbol value.
Symbol('user');
export function function setUserContext(user: User): void
setUserContext(user: User
user: type User = /*unresolved*/ any
User) {
setContext<User>(key: any, context: User): User
Associates an arbitrary context
object with the current component and the specified key
and returns that object. The context is then available to children of the component
(including slotted content) with getContext
.
Like lifecycle functions, this must be called during component initialisation.
setContext(let userKey: symbol
userKey, user: User
user);
}
export function function getUserContext(): User
getUserContext(): type User = /*unresolved*/ any
User {
return getContext<User>(key: any): User
Retrieves the context that belongs to the closest parent component with the specified key
.
Must be called during component initialisation.
getContext(let userKey: symbol
userKey) as type User = /*unresolved*/ any
User;
}