Svelte/Sapper.js - 如何使用 localStorage 数据初始化存储?

Posted

技术标签:

【中文标题】Svelte/Sapper.js - 如何使用 localStorage 数据初始化存储?【英文标题】:Svelte/Sapper.js - How to initialize store with localStorage data? 【发布时间】:2019-10-31 08:51:44 【问题描述】:

我来自 React 背景,但我正在为我的下一个应用程序切换到 Svelte 和 Sapper,以应对 React 带来的巨大包大小。但是,我在使用从 localStorage 检索到的数据初始化 Svelte 存储时遇到了问题。

根据 Sapper 文档 (https://sapper.svelte.dev/docs#Getting_started),我通过从命令行运行 npx degit "sveltejs/sapper-template#rollup" my-app 创建了我的项目。然后我安装了依赖项并删除了src文件夹中的演示代码。

然后我创建了两个文件:src/routes/index.sveltesrc/store/index.js

两者的代码:

src/store/index.js

    import writable from "svelte/store";
    
    export let userLang;
    
    if(typeof window !== "undefined") 
        userLang = writable(localStorage.getItem("lang") || "en");
     else 
        userLang = writable(null);
    

src/routes/index.svelte

    <script>
        import userLang from "../store";
    </script>
    
    <p>Your Preferred Language: $userLang</p>

当我运行应用程序并点击index 路由时,我看到了:

您的首选语言:null

然后几乎立即更新并更改为

您的首选语言:zh

当localStorage中没有lang项时,改为

您的首选语言:fr

在从开发者控制台显式设置localStorage.setItem("lang", "fr") 并刷新之后。

我知道商店首先在服务器上初始化,windowundefined,然后在客户端上重新水化。所以这种行为是意料之中的。

所以我的问题是:我怎样才能完全跳过服务器初始化?是否可以只在客户端(定义localStorage)上设置商店,以便用户选择的语言立即可用?

在用户选择更改他们的首选语言后,我不能默认使用英语或任何其他语言。我也无法在初始页面加载时通过navigator.language 从浏览器获取用户语言,因为navigator 在服务器上也是undefined

并且在商店重新水化之前出现一闪而过的空文本会搞砸我的应用程序的用户体验,尤其是当userLang 的值将在整个地方使用翻译时。

因此,任何对此的策略或技巧都绝对值得赞赏。

**** 更深层次的问题 ****

我实际上更愿意为这个应用程序提供服务器端渲染,但我确实需要 Sapper 提供的所有其他出色功能,例如路由、预取和静态站点构建。

所以我尝试按照docs 运行npx sapper export 以生成一个完全静态的站点,以便从等式中删除服务器,但仍然会出现完全相同的问题,即使没有服务器正在使用全部。

有人对如何配置 Sapper 并关闭 s-s-r 但保留其他功能有任何建议吗?

谢谢!

**** 更新 ****

根据 Rich Harris 的回答,用 #if process.browser 包装标记就可以了。所以我更新了src/routes/index.svelte文件,如下所示:

    <script>
        import userLang from "../store";
    </script>

    #if process.browser
        <p>Your Preferred Language: $userLang</p>
    /if

userLang 变量立即设置为来自localStorage 的值或默认为en,正如我在这个简单的演示中所打算的那样。 null 没有更多的闪光,所以它基本上表现得像它只是在这一点上的客户端。

我将努力充实我的项目,看看是否还有其他问题。到那时,我认为这解决了我的问题。

【问题讨论】:

【参考方案1】:

目前,s-s-r 是非可选的。 SPA 模式存在一个问题 - https://github.com/sveltejs/sapper/issues/383 - 如您所描述的那样,我们只需要解决它。

我们还计划在未来的版本中内置对 i18n 的支持:https://github.com/sveltejs/sapper/issues/576

与此同时,您可以通过将所有标记包装在 #if process.browser 中来伪造它——其中的任何内容都不会被服务器渲染,但会在 javascript 启动后立即呈现。

【讨论】:

感谢您的回复!我一定会密切关注这些问题,并尝试按照您所说的将标记包装在 if 块中。还要感谢 Svelte 的全方位魅力。我知道随着时间的推移,这个项目只会越来越好 我的令牌存储在 localStorage 中,我如何使用 sapper 解决这个问题? 值得注意的是,检查process.browser 似乎也适用于常规 JS 代码,而不仅仅是在模板中。谢谢! process.browser 在我的构建环境中工作。但是当我导出时它不起作用。

以上是关于Svelte/Sapper.js - 如何使用 localStorage 数据初始化存储?的主要内容,如果未能解决你的问题,请参考以下文章

如果 x 在集合 L 中,如何使用 lambda 函数创建返回 true 的函数 L

使用ggplotly()时如何修改直方图的hovertemplate?

如何使用“l = new LoadVars ();”这样的代码迁移到 AS3

如何使用带有 R 的 L-BFGS 执行逻辑回归?

如何在 Fragment l 中使用 WebView? [关闭]

如何导入 RecyclerView for Android L-preview