Skip to main content

Context

Context を使うと、コンポーネントは親コンポーネントが所有する値に、 props を介さずアクセスできます。(中間コンポーネントを何層も経由する’prop-drilling’という手法を回避できます。) 親コンポーネントは setContext(key, value) で context を設定します...

Parent
<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 を取得します:

Child
<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.svelteChild.svelte を直接含んでおらず, children snippet の一部としてレンダリングするとき、特に便利です。 (デモ):

<Parent>
	<Child />
</Parent>

キー (上記の例では 'my-context') と context 自体を、任意の JavaScript の値にすることができます。

setContextgetContext に加えて、 Svelte は hasContextgetAllContexts 関数を提供しています。

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

便利なパターンとして、型安全性を維持できるヘルパー関数で setContextgetContext の呼び出しをラップする方法があります:

context
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
@paramuser
setUserContext
(user: User
@paramuser
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
@paramuser
user
);
} export function function getUserContext(): UsergetUserContext() { 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): voidsetUserContext(user: Useruser: 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: Useruser);
} export function function getUserContext(): UsergetUserContext() { 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 を独自のモジュールに配置し、必要に応じてインポートしたくなるかもしれません:

state.svelte
export const 
const myGlobalState: {
    user: {};
}
myGlobalState
=
function $state<{
    user: {};
}>(initial: {
    user: {};
}): {
    user: {};
} (+1 overload)
namespace $state

Declares reactive state.

Example:

let count = $state(0);

https://svelte.dev/docs/svelte/$state

@paraminitial The initial value
$state
({
user: {}user: { // ... } // ... });

大部分のケースではまったく問題ありませんが、リスクがあります。サーバーサイドレンダリング中に state を変更すると(これは非推奨ですが、完全に可能です!)...

App
<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

previous next