SvelteKit中如何从异步函数在全局设置本地存储上下文?
SvelteKit异步加载LocalStorage偏好并设置Context的解决方案
问题原因
你在layout.ts的load函数里调用setContext失败,是因为setContext只能在组件初始化的同步代码中执行,而load是数据加载钩子,不属于组件初始化流程,所以会抛出Function called outside component initialization错误。
正确实现方式
1. 保留现有可写Store
这个Store作为偏好数据的容器,默认值用初始配置:
// 示例:src/lib/stores.ts import { writable } from 'svelte/store'; export const localStoragePreferences = writable(new LocalStoragePreferences());
2. 在根+layout.svelte中处理Context与异步加载
根组件是应用的最高层级,在这里可以安全调用setContext,并在客户端异步加载LocalStorage数据更新Store:
<script> import { setContext, onMount } from 'svelte'; import { localStoragePreferences } from '$lib/stores'; import { queryLocalStoragePreferences } from '$lib/utils'; // 初始化Context,将Store传入(核心:用Store作为Context值,实现异步更新的自动同步) setContext('localStoragePreferences', localStoragePreferences); // 仅在客户端执行LocalStorage读取(服务器端无LocalStorage) onMount(async () => { const realPrefs = await queryLocalStoragePreferences(); localStoragePreferences.set(realPrefs); }); </script> <slot />
3. 子组件中使用Context
在任意子组件中,通过getContext获取Store后即可使用:
<script> import { getContext } from 'svelte'; const prefsStore = getContext('localStoragePreferences'); </script> <!-- 自动订阅Store,数据更新时自动渲染 --> <div>当前主题:{$prefsStore.theme}</div>
方案优势
- 符合Svelte的Context规则:
setContext在组件初始化阶段调用,避免报错 - 利用Store的响应式特性,异步加载完成后自动同步到所有依赖组件
onMount确保LocalStorage操作仅在客户端执行,避免SSR环境下的错误
内容的提问来源于stack exchange,提问作者Patrick Kenny
相关产品推荐
相关产品推荐

