AstroでReactを使う方法

AstroプロジェクトでReactコンポーネントを効果的に使用する方法を、実例とともに解説します。

Tech Blog 編集部 | 2024-11-19 | 7分

Astroは複数のUIフレームワークをサポートしていますが、その中でもReactは最も人気があります。既存のReactコンポーネントを再利用できるのは大きなメリットです。

1. Reactインテグレーションの追加

Terminal window
npx astro add react

このコマンドで以下が自動的に設定されます:

  • React関連パッケージのインストール
  • astro.config.mjsの更新
  • tsconfig.jsonの設定

2. 手動セットアップ

自動セットアップが使えない場合は、手動で設定できます:

Terminal window
npm install @astrojs/react react react-dom
astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
export default defineConfig({
integrations: [react()],
});

インタラクティブなコンポーネント

src/components/SearchBox.tsx
import { useState } from 'react';
interface SearchBoxProps {
onSearch: (query: string) => void;
}
export function SearchBox({ onSearch }: SearchBoxProps) {
const [query, setQuery] = useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSearch(query);
};
return (
<form onSubmit={handleSubmit} className="flex gap-2">
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="検索..."
className="flex-1 px-4 py-2 border rounded"
/>
<button type="submit" className="px-6 py-2 bg-blue-500 text-white rounded">
検索
</button>
</form>
);
}

Astroページでの使用

src/pages/search.astro
---
import Layout from '../layouts/Layout.astro';
import { SearchBox } from '../components/SearchBox';
---
<Layout title="検索">
<div class="container mx-auto p-8">
<h1>記事を検索</h1>
<!-- client:loadで即座にハイドレーション -->
<SearchBox client:load onSearch={(q) => console.log(q)} />
</div>
</Layout>

client:load

ページロード直後に必要な重要なコンポーネント(ナビゲーションメニューなど)に使用:

<Navigation client:load />

client:idle

優先度の低いコンポーネント(チャットウィジェット、広告など)に使用:

<ChatWidget client:idle />

client:visible

スクロールして表示されるコンポーネント(コメント欄、画像ギャラリーなど)に使用:

<CommentSection client:visible />

client:media

レスポンシブなコンポーネント(モバイルメニューなど)に使用:

<MobileMenu client:media="(max-width: 768px)" />

静的Props

---
const title = "記事タイトル";
const tags = ["React", "Astro"];
---
<ArticleCard
client:idle
title={title}
tags={tags}
/>

関数Props(注意点)

関数をpropsとして渡す場合は、そのコンポーネントをハイドレーションする必要があります:

<!-- ❌ これは動作しません -->
<Button onClick={() => console.log('click')} />
<!-- ✅ client:*ディレクティブが必要 -->
<Button client:idle onClick={() => console.log('click')} />

ローカル状態

単純な状態はuseStateで管理:

import { useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
カウント: {count}
</button>
);
}

グローバル状態

複数のコンポーネント間で状態を共有する場合は、Zustandやnanostoresを使用:

store.ts
import { atom } from 'nanostores';
export const $cartItems = atom<string[]>([]);
CartButton.tsx
import { useStore } from '@nanostores/react';
import { $cartItems } from '../store';
export function CartButton() {
const items = useStore($cartItems);
return <button>カート ({items.length})</button>;
}

1. コンポーネントの遅延ロード

---
// 重いコンポーネントは遅延ロード
---
<HeavyChart client:visible />

2. 静的レンダリングの活用

インタラクティブでない部分はAstroコンポーネントで:

<!-- Astroコンポーネント(静的) -->
<article class="prose">
<h1>{post.title}</h1>
<div set:html={post.content} />
</article>
<!-- Reactコンポーネント(インタラクティブ) -->
<LikeButton client:visible postId={post.id} />

AstroとReactの組み合わせにより:

  • 既存のReactコンポーネントを再利用
  • 必要な部分だけJSを配信
  • 高速なページロードを実現
  • 優れたSEOを維持

アイランドアーキテクチャの思想を理解して、適切にクライアントディレクティブを使い分けることが重要です。

関連記事

Portfolio

Astro、React、Framer Motion、Three.jsで構築されたポートフォリオサイト

技術スタック

  • Astro
  • React
  • Framer Motion
  • Three.js
  • TailwindCSS
  • shadcn/ui

© 2026 Portfolio. All rights reserved.