初めてのAstroアイランドを作成する
Preactコンポーネントを使い、ランダムに選択されたメッセージでサイト訪問者に挨拶しましょう!
ここで学ぶことは...
- AstroプロジェクトにPreactを追加する
- ホームページにAstroアイランド(Preactの
.jsxコンポーネント)を追加する - アイランドをインタラクティブにするために
client:ディレクティブを使用する
AstroプロジェクトにPreactを追加する
動作中であれば開発サーバーを停止し、ターミナルを使用できるようにします(キーボードショートカットはCtrl + Cです)。
以下のコマンドを実行して、AstroプロジェクトでPreactコンポーネントを使用できるようにします。
npx astro add preactpnpm astro add preactyarn astro add preactコマンドラインの指示に従って、プロジェクトにPreactを追加します。
Preactの挨拶用バナーを追加する
このコンポーネントは、挨拶用メッセージの配列をpropとして受け取り、その中からランダムに1つを選んでウェルカムメッセージとして表示します。ユーザーはボタンをクリックして新しいメッセージをランダムに受け取れます。
src/components/にGreeting.jsxという名前の新しいファイルを作成します。.jsxというファイル拡張子が使われていることに注意してください。このファイルはAstroではなくPreactで書きます。以下のコードを
Greeting.jsxに追加します。import { useState } from 'preact/hooks'; export default function Greeting({messages}) { const randomMessage = () => messages[(Math.floor(Math.random() * messages.length))]; const [greeting, setGreeting] = useState(messages[0]); return ( <div> <h3>{greeting}! 訪問いただきありがとうございます!</h3> <button onClick={() => setGreeting(randomMessage())}> 新しい挨拶 </button> </div> ); }ホームページの
index.astroでこのコンポーネントをインポートして使用します。--- import BaseLayout from '../layouts/BaseLayout.astro'; import Greeting from '../components/Greeting'; const pageTitle = "Home Page"; --- <BaseLayout pageTitle={pageTitle}> <h2>私の素晴らしいブログのサブタイトル</h2> <Greeting messages={["どうも", "こんにちは", "初めまして", "ようこそ"]} /> </BaseLayout>ブラウザのプレビューを確認すると、ランダムな挨拶が表示されますが、ボタンは機能していないはずです。
client:loadディレクティブを使用して、2つ目の<Greeting />コンポーネントを追加します。--- import BaseLayout from '../layouts/BaseLayout.astro'; import Greeting from '../components/Greeting'; const pageTitle = "Home Page"; --- <BaseLayout pageTitle={pageTitle}> <h2>私の素晴らしいブログのサブタイトル</h2> <Greeting messages={["どうも", "こんにちは", "初めまして", "ようこそ"]} /> <Greeting client:load messages={["Hej", "Hallo", "Hola", "Habari"]} /> </BaseLayout>ページを再度確認し、2つのコンポーネントを比較します。2番目のボタンが機能しているのは、
client:loadディレクティブによって、ページがロードされたときにJavaScriptをクライアントに送信して再実行するようAstroに指示しているためです。これにより、コンポーネントはインタラクティブになります。これは ハイドレートされた(hydrated) コンポーネントと呼ばれます。違いがわかったら、ハイドレートされていないGreetingコンポーネントを削除します。
--- import BaseLayout from '../layouts/BaseLayout.astro'; import Greeting from '../components/Greeting'; const pageTitle = "Home Page"; --- <BaseLayout pageTitle={pageTitle}> <h2>私の素晴らしいブログのサブタイトル</h2> <Greeting messages={["どうも", "こんにちは", "初めまして", "ようこそ"]} /> <Greeting client:load messages={["Hej", "Hallo", "Hola", "Habari"]} /> </BaseLayout>
パターンを分析する
client:ディレクティブは他にもあり、それぞれが異なるタイミングでJavaScriptをクライアントに送信します。たとえばclient:visibleは、コンポーネントがページ上に表示されたタイミングで対応するJavaScriptを送信します。
次のようなコードをもつAstroコンポーネントについて考えてみましょう。
---
import BaseLayout from '../layouts/BaseLayout.astro';
import AstroBanner from '../components/AstroBanner.astro';
import PreactBanner from '../components/PreactBanner';
import SvelteCounter from '../components/SvelteCounter.svelte';
---
<BaseLayout>
<AstroBanner />
<PreactBanner />
<PreactBanner client:load />
<SvelteCounter />
<SvelteCounter client:visible />
</BaseLayout>5つのコンポーネントのうち、JavaScriptをクライアントに送信し、ハイドレートされるアイランドになるのはどれですか?
2つの
<PreactBanner />コンポーネントで共通している点はどこですか?逆に異なる点はどこでしょうか?SvelteCounterコンポーネントは数値を表示し、それを増やすためのボタンをもっているとします。ウェブサイトのソースコードを見ることはできず、公開されたページのみ確認できるとき、client:visibleを使用しているのは2つの<SvelteCounter />コンポーネントのうちどちらか、どのように判断すればよいでしょうか?
確認テスト
以下のコンポーネントのそれぞれについて、ブラウザに送信される内容を選択してください。
<ReactCounter client:load /><SvelteCard />