Open1

solidstartで、storeの値をstorageに永続化する

yunayuna

solidのstoreを永続化するモジュールとして、@solid-primitives/storage が使えます。
https://primitives.solidjs.community/package/storage/

ただし、localStorageに対応していないSSRでこれを使うと、これを読み込んだ瞬間にエラーになります。

そこで、isServerフラグを使って分岐させることで、回避することができます。

package.json
"dependencies": {
    "@solid-primitives/storage": "^4.3.1",
...
mode.ts
import { createStore } from "solid-js/store";
import { makePersisted } from "@solid-primitives/storage";
import { isServer } from "solid-js/web";

const [store, setStore] = createStore({
  mode: 2, //default value
});

export const [windowStore, setWindowStore, init] = isServer ? [store, setStore, () => {}] : makePersisted([store, setStore]);

これを表示させる部分も、clientOnlyにしておくと、開発時も変な動きがありません。

solidのClientOnlyは通常、componentしか指定できないので、取り回しの良いヘルパー関数を用意しておく
https://docs.solidjs.com/solid-start/reference/client/client-only

これはエラー

<div>
{clientOnly(() => <div>mode: {sampleStore.mode}</div>)}
</div>

これだとOK

util.ts
import { clientOnly } from "@solidjs/start";
import { Component, JSX } from "solid-js";

export function createInlineClientOnly(Component: () => JSX.Element) {
    const ClientComp = clientOnly(() => Promise.resolve({
      default: Component
    }));
    return <ClientComp />;
  }

sample.tsx
<div>
{createInlineClientOnly(() => <div>mode: {sampleStore.mode}</div>)}
</div>