【发布时间】: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.svelte 和 src/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") 并刷新之后。
我知道商店首先在服务器上初始化,window 是undefined,然后在客户端上重新水化。所以这种行为是意料之中的。
所以我的问题是:我怎样才能完全跳过服务器初始化?是否可以只在客户端(定义localStorage)上设置商店,以便用户选择的语言立即可用?
在用户选择更改他们的首选语言后,我不能默认使用英语或任何其他语言。我也无法在初始页面加载时通过navigator.language 从浏览器获取用户语言,因为navigator 在服务器上也是undefined。
并且在商店重新水化之前出现一闪而过的空文本会搞砸我的应用程序的用户体验,尤其是当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 没有更多的闪光,所以它基本上表现得像它只是在这一点上的客户端。
我将努力充实我的项目,看看是否还有其他问题。到那时,我认为这解决了我的问题。
【问题讨论】:
标签: javascript state server-side-rendering svelte sapper