Astroは、モダンなフロントエンド開発のための新しい静的サイトジェネレータです。しかし、AstroとReact.jsを組み合わせて使用する際に、ReactのuseContext
が期待通りに動作しないことがあります。この記事では、その問題とその解決策について解説します。
useContextの問題点
Astroのislandsアーキテクチャや部分的なハイドレーションを使用すると、コンポーネント間での状態の共有が難しくなることがあります。特に、ReactのuseContext
を使用して状態を共有しようとすると、期待通りに動作しないことが報告されています。
nanostores で useContextの代替
この問題の解決策として、nanostores
というライブラリを使用することが推奨されています。nanostores
は、フレームワークに依存しない状態管理のための軽量なライブラリで、AstroとReactの間での状態の共有をシームレスに行うことができます。
nanostores/persistent で 状態の永続化
さらに、nanostores
の拡張としてnanostores/persistent
を使用することで、状態をlocalStorage
に保存し、ページのリロードやブラウザの再起動後も状態を保持することができます。
永続化の導入手順例
必要なパッケージのインストール
まず、nanostores
とnanostores/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
の問題は、nanostores
とnanostores/persistent
を使用することで解決することができます。これにより、AstroとReactの強力な組み合わせを最大限に活用しながら、効果的な状態管理を行うことができます。