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

时间:2019-06-17 18:14:27

标签: javascript state serverside-rendering svelte sapper

我来自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

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

  

您的首选语言:

在localStorage中没有lang项并且更改为

  

您的首选语言:fr

在开发者控制台中明确设置localStorage.setItem("lang", "fr")并刷新后。

我知道商店首先在windowundefined的服务器上初始化,然后在客户端重新补水。因此,这种行为是预期的。

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

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

在商店重新命名之前,会出现空白文本提示,这会弄乱我的应用程序的UX,尤其是当userLang的值将在翻译中随处使用时。

因此,对此表示赞赏的任何策略或技巧。

**** 更深的问题 ****

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

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

有人对如何配置Sapper和关闭SSR但保留其他功能有任何建议吗?

谢谢!

**** 更新 ****

按照里奇·哈里斯(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 个答案:

答案 0 :(得分:2)

当前,SSR是非可选的。 SPA模式存在一个问题https://github.com/sveltejs/sapper/issues/383,它会按照您描述的方式运行,我们只需要解决这个问题即可。

我们还计划在以后的版本中https://github.com/sveltejs/sapper/issues/576

内置对i18n的支持。

同时,您可以通过将所有标记包装在{#if process.browser}中来伪造它-内部的任何内容都不会由服务器呈现,但是一旦JavaScript插入就会显示出来。