web-dev-qa-db-ja.com

Svelte / Sapper.js-localStorageデータでストアを初期化する方法

私はReact背景から来ましたが、Reactこれらのしかし、localStorageから取得したデータでSvelteのストアを初期化するのに問題があります。

Sapperのドキュメント( https://sapper.svelte.dev/docs#Getting_started )に従って、コマンドラインから_npx degit "sveltejs/sapper-template#rollup" my-app_を実行してプロジェクトを作成しました。次に、依存関係をインストールし、srcフォルダーのデモコードを削除しました。

次に、2つのファイルを作成しました:_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

その後、ほぼ即座に更新および変更されます

お好みの言語:en

localStorageにlangアイテムがなく、

ご希望の言語:fr

開発者コンソールからlocalStorage.setItem("lang", "fr")を明示的に設定して更新した後。

windowundefinedであるサーバーでストアが最初に初期化され、次にクライアントで再水和されていることを知っています。したがって、この動作は予想されたものです。

だから私の質問は、サーバーの初期化を完全にスキップするにはどうすればよいですか?ユーザーの選択した言語がすぐに利用できるように、クライアント(localStorageが定義されている場所)でのみストアをセットアップすることは可能ですか?

ユーザーが希望する言語を変更することを選択した後、デフォルトですべてを英語またはその他の言語にすることはできません。サーバーのnavigatorundefinedなので、最初のページの読み込み時に_navigator.language_を介してブラウザーからユーザーの言語を取得することもできません。

また、特にuserLangの値が翻訳のあちこちで使用される場合は、ストアのリハイデートがアプリケーションのUXを台無しにする前に、空のテキストが少し表示されます。

したがって、このための戦略やハックは間違いなく高く評価されています。

****より深い問題****

私は実際にはこのアプリケーションに対してサーバーサイドレンダリングをしないことを望んでいますが、ルーティングなど、Sapperが提供する他のすべての優れた機能が必要です、プリフェッチ、静的サイト構築。

したがって、 docs に従って_npx sapper export_を実行して、サーバーを方程式から削除するために完全に静的なサイトを生成しようとしましたが、まったく同じ問題が依然として発生しますが、サーバーはまったく使用されていません。

Sapperを構成してSSRをオフにする方法に関するアドバイスはありますか?

ありがとうございました!

****更新****

Rich Harrisの回答によると、マークアップを_{#if process.browser}_でラップすることで、トリックはうまく機能します。だから私は次のように_src/routes/index.svelte_ fileを更新しました:

_<script>
    import {userLang} from "../store";
</script>

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

そして、userLang変数はすぐにlocalStorageの値で設定されるか、デフォルトでenに設定されます。 nullのフラッシュがなくなるため、基本的にはこの時点でのみクライアント側のように動作します。

私は自分のプロジェクトを具体化することに取り組み、遭遇する問題が他にないかどうかを確認します。それまでは、これで私の問題は解決すると思います。

10
another_one

現在、SSRはオプションではありません。 SPAモードについて未解決の問題があります— https://github.com/sveltejs/sapper/issues/38 —これは、説明どおりに動作するため、問題を解決する必要があります。

また、将来のリリースでi18nの組み込みサポートを計画しています: https://github.com/sveltejs/sapper/issues/576

それまでの間、すべてのマークアップを{#if process.browser} —内部はサーバーレンダリングされませんが、JavaScriptが起動するとすぐに存在します。

10
Rich Harris