Context
Context を使うと、コンポーネントは親コンポーネントが所有する値に、 props を介さずアクセスできます。(中間コンポーネントを何層も経由する’prop-drilling’という手法を回避できます。) 親コンポーネントは setContext(key, value)
で context を設定します...
<script>
import { setContext } from 'svelte';
setContext('my-context', 'hello from Parent.svelte');
</script>
<script lang="ts">
import { setContext } from 'svelte';
setContext('my-context', 'hello from Parent.svelte');
</script>
...そして、子コンポーネントは getContext
で context を取得します:
<script>
import { getContext } from 'svelte';
const message = getContext('my-context');
</script>
<h1>{message}, inside Child.svelte</h1>
<script lang="ts">
import { getContext } from 'svelte';
const message = getContext('my-context');
</script>
<h1>{message}, inside Child.svelte</h1>
これは、 Parent.svelte
が Child.svelte
を直接含んでおらず, children
snippet の一部としてレンダリングするとき、特に便利です。 (デモ):
<Parent>
<Child />
</Parent>
キー (上記の例では 'my-context'
) と context 自体を、任意の JavaScript の値にすることができます。
setContext
と getContext
に加えて、 Svelte は hasContext
と getAllContexts
関数を提供しています。
state と context を使用する
リアクティブな state を context に保存できます (デモ)...
<script>
import { setContext } from 'svelte';
import Child from './Child.svelte';
let counter = $state({
count: 0
});
setContext('counter', counter);
</script>
<button onclick={() => counter.count += 1}>
increment
</button>
<Child />
<Child />
<Child />
...ただし、 counter
を 再代入する (更新ではなく)と「リンクが切れる」点に注意してください。 つまり、次のようにするのではなく...
<button onclick={() => counter = { count: 0 }}>
reset
</button>
...次のようにします:
<button onclick={() => counter.count = 0}>
reset
</button>
もしあなたが間違えても、 Svelte が警告してくれます。
型安全な context
便利なパターンとして、型安全性を維持できるヘルパー関数で setContext
と getContext
の呼び出しをラップする方法があります:
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';
const const key: {}
key = {};
/** @param {User} user */
export function function setUserContext(user: User): void
setUserContext(user: User
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(const key: {}
key, user: User
user);
}
export function function getUserContext(): User
getUserContext() {
return /** @type {User} */ (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(const key: {}
key));
}
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';
const const key: {}
key = {};
export function function setUserContext(user: User): void
setUserContext(user: User
user: 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(const key: {}
key, user: User
user);
}
export function function getUserContext(): User
getUserContext() {
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(const key: {}
key) as User;
}
グローバル state の置き換え
多くの異なるコンポーネントで共有される state があるとき、 state を独自のモジュールに配置し、必要に応じてインポートしたくなるかもしれません:
export const const myGlobalState: {
user: {};
}
myGlobalState = function $state<{
user: {};
}>(initial: {
user: {};
}): {
user: {};
} (+1 overload)
namespace $state
$state({
user: {}
user: {
// ...
}
// ...
});
大部分のケースではまったく問題ありませんが、リスクがあります。サーバーサイドレンダリング中に state を変更すると(これは非推奨ですが、完全に可能です!)...
<script>
import { myGlobalState } from './state.svelte.js';
let { data } = $props();
if (data.user) {
myGlobalState.user = data.user;
}
</script>
<script lang="ts">
import { myGlobalState } from './state.svelte.js';
let { data } = $props();
if (data.user) {
myGlobalState.user = data.user;
}
</script>
...すると、そのデータに 次の ユーザーがアクセスできる可能性があります。 context はリクエスト間で共有されないため、この問題を解決します。
Edit this page on GitHub llms.txt