我来自 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
路线时,我看到了:
您的首选语言:空
然后几乎立即更新并更改为
您的首选语言:en
当 localStorage 中没有lang
项目时,更改为
您的首选语言:fr
localStorage.setItem("lang", "fr")
从开发者控制台显式设置并刷新后。
我知道商店首先在服务器上初始化window
,undefined
然后在客户端上重新水化。所以这种行为是意料之中的。
所以我的问题是:我怎样才能完全跳过服务器初始化?是否可以只在客户端设置商店(在哪里localStorage
定义),以便用户选择的语言立即可用?
在用户选择更改他们的首选语言后,我不能默认使用英语或任何其他语言。我也无法通过navigator.language
初始页面加载从浏览器获取用户语言,因为navigator
它undefined
也在服务器上。
并且在商店重新水化之前出现一闪而过的空文本会搞砸我的应用程序的用户体验,特别是当userLang
翻译的值将在整个地方使用时。
因此,对此的任何策略或技巧都绝对值得赞赏。
****更深层次的问题****
实际上,我更希望这个应用程序根本没有服务器端渲染,但我确实需要 Sapper 提供的所有其他出色功能,例如路由、预取和静态站点构建。
因此,我尝试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
变量立即设置为值 fromlocalStorage
或默认值,en
正如我在这个简单演示中所打算的那样。没有更多的闪光null
,所以它基本上表现得像它只是在这一点上的客户端。
我将努力充实我的项目,看看是否还有其他问题。到那时,我认为这解决了我的问题。