Astro × React.js: useContextの問題とnanostoresを使った解決策

ウェブ制作
はる
はる

Astroは、モダンなフロントエンド開発のための新しい静的サイトジェネレータです。しかし、AstroとReact.jsを組み合わせて使用する際に、ReactのuseContextが期待通りに動作しないことがあります。この記事では、その問題とその解決策について解説します。

useContextの問題点

Astroのislandsアーキテクチャや部分的なハイドレーションを使用すると、コンポーネント間での状態の共有が難しくなることがあります。特に、ReactのuseContextを使用して状態を共有しようとすると、期待通りに動作しないことが報告されています。

nanostores で useContextの代替

この問題の解決策として、nanostoresというライブラリを使用することが推奨されています。nanostoresは、フレームワークに依存しない状態管理のための軽量なライブラリで、AstroとReactの間での状態の共有をシームレスに行うことができます。

Share State Between Islands
Learn how to share state across framework components with Nano Stores.

nanostores/persistent で 状態の永続化

さらに、nanostoresの拡張としてnanostores/persistentを使用することで、状態をlocalStorageに保存し、ページのリロードやブラウザの再起動後も状態を保持することができます。

GitHub - nanostores/persistent: Smart store for Nano Stores state manager to keep data in localStorage
Smart store for Nano Stores state manager to keep data in localStorage - GitHub - nanostores/persistent: Smart store for...

永続化の導入手順例

必要なパッケージのインストール

まず、nanostoresnanostores/persistentをインストールします。

npm install nanostores @nanostores/persistent

永続的なストアの作成

新しいファイルsrc/stores/loginStore.tsを作成し、以下の内容を追加します。

import { persistentAtom } from '@nanostores/persistent';

export const statusStore = persistentAtom<'loggedOut' | 'loggedIn'>('loginStatus', 'loggedOut');

コンポーネントでのストアの使用

LoginButtonコンポーネントでlogInFlagStoreを使用して、ログインの状態を管理します。

import React from "react";
import { useStore } from '@nanostores/react';
import { statusStore } from "@stores/loginStore";

const LoginButton: React.FC = () => {
  const status = useStore(statusStore);

  const toggleLogin = () => {
    statusStore.set(status === 'loggedIn' ? 'loggedOut' : 'loggedIn');
  };

  return (
    <>
      <button type="button" onClick={toggleLogin}>
        {status === 'loggedIn' ? "ログアウト" : "ログイン"}
      </button>
    </>
  );
};

export default LoginButton;

この手順により、statusの状態はlocalStorageに保存され、ページのリロード後も状態が保持されます。

まとめ

AstroとReact.jsを組み合わせて使用する際のuseContextの問題は、nanostoresnanostores/persistentを使用することで解決することができます。これにより、AstroとReactの強力な組み合わせを最大限に活用しながら、効果的な状態管理を行うことができます。

タイトルとURLをコピーしました