islandsへのデータ受渡 と オブジェクトからの項目除去
2024年11月20日

islandsへのデータ受渡 と オブジェクトからの項目除去

1,929文字(読了まで約5分)
headerimage

HonoX での islands 実装をする際に、islands コンポーネントで初期表示させる値は、SSR のコンポーネントから引き渡すことができます。

ただ、どんな値でも渡せるわけではありません。クライアント ⇔ サーバ間の通信を経由しますので、データ化できて、元のオブジェクトに復元できるものでなくてはなりません。 この特徴をシリアライズ可能といいますが、あまり分かっていないので、ちょっと詳細な説明まではできません・・・

next.js でも server action に渡せるパラメータなどは、このシリアライズ可能な型に限られています。

react のドキュメント

no image

https://react.dev/reference/rsc/use-server#serializable-parameters-and-return-values


Hono で扱う環境変数を型定義すると、Bindings の中にサービスとのバインド設定も含むため、islands に渡す必要のないデータが含まれてしまいます。

// HonoのEnv型
export type EnvType = {
  // contextで扱う型
  Variables: {
    user: User | undefined;
  };
  // Cloudflareサービス・環境変数とのバインド設定
  Bindings: {
    DB: D1Database; // ← D1Databaseという複雑なデータ(islandsには不要)
    API_SERVER: string; // ← islandsに渡したいのはこちら
  };
};
const Main: FC = async () => {
  const c = useRequestContext<EnvType>();
  const envValue = c.env;
 
  return (
    <>
      {/* islandsコンポーネントの呼び出し(エラーになる) */}
      <IslandComponent envValue={envValue} />{" "}
    </>
  );
};

不要なプロパティを islands に渡さないようにするため、プロパティ除去関数を作ります。

export const omitProps = <T extends object, K extends keyof T>(
  obj: T,
  keys: K[]
): Omit<T, K> => {
  const result = { ...obj };
  for (const key of keys) {
    delete result[key];
  }
  return result;
};

呼び出し方は以下のとおり

const Main: FC = async () => {
  const c = useRequestContext<EnvType>();
  const envValue = omitProps(c.env, ["DB"]);
 
  return (
    <>
      {/* islandsコンポーネントの呼び出し(DBが含まれないので、シリアライズ可能となりOK) */}
      <IslandComponent envValue={envValue} />
    </>
  );
};

  • SSR から islands へ送るデータをシリアライズ可能とするため、余分なプロパティを除去するユーティリティを作成しました。
  • 関数化することで、読みやすくメンテナンスしやすい形で実装ができました。
  • 今回、シリアライズできないデータを除外する使い方をしましたが、セキュリティ上、クライアントに渡してはいけない値を削除する等としても使えると思います。

以上です。

- コメント -

    このサイトではcookieを利用して、サイト訪問者の識別に利用します。 cookieの利用に同意いただくことで、サイト訪問者は記事のいいね機能等をご利用いただけます。 なお、サイト運営者はアクセス統計としてcookieの情報を利用する場合があります。