Astro 「群島架構」Nano Stores 繼續學習

更新 發佈閱讀 9 分鐘

Nano Stores與其它的狀態管理工具(如 Redux 或 Pinia)不同
Nano Stores 是 不可知框架(Framework-agnostic) 的。這意味著你可以在同一個 Astro 專案中,讓 React、Vue、Svelte 和原生 JS 共享同一個狀態。


第一階段:核心概念與環境設定

Nano Stores 的核心是 Atoms(單一值)和 Maps(物件結構)。它們是「訂閱制」的,只有在元件真正掛載到瀏覽器時才會運作。

1. 安裝

在你的 Astro 專案中執行:

npm install nanostores @nanostores/react # 如果你用 React
# 或者
npm install nanostores @nanostores/vue # 如果你用 Vue

2. 建立你的第一個 Store

在 src 下建立一個 store.js

import { atom } from 'nanostores'

// 定義一個初始值為 0 的 Atom
export const $counter = atom(0)

第二階段:在 Astro 元件中使用(群島通訊)

這是最常見的情境:你有一個按鈕(React)和一個顯示面板(Vue),它們需要同步數據。

練習 1:基礎計數器

步驟 A:建立 React 按鈕 (src/components/Button.jsx)

import { $counter } from '../store'

export default function Button() {
return <button onClick={() => $counter.set($counter.get() + 1)}>1</button>
}

步驟 B:建立原生 JS 顯示器 (src/components/Display.astro) 在 Astro 的 <script> 標籤中,你需要使用 .subscribe 來監聽變化:

<div id="display">0</div>

<script>
import { $counter } from '../store'

const div = document.querySelector('#display')
// 訂閱變化,當 $counter 改變時更新 DOM
$counter.subscribe((value) => {
div.textContent = value.toString()
})
</script>

第三階段:處理複雜數據(Maps)

練習 2:使用者設定檔

建立 Store:

import { map } from 'nanostores'

export const $user = map({
name: 'Guest',
role: 'Visitor',
})

// 更新函數
export function updateName(newName) {
$user.setKey('name', newName)
}

第四階段:進階技巧與非同步數據

練習 3:從 API 獲取數據

Nano Stores 可以處理非同步狀態。這在 Astro 中處理客戶端數據請求非常有用。

import { atom, onMount } from 'nanostores'

export const $data = atom([])

onMount($data, () => {
// 當有人訂閱 $data 時,這段代碼才會執行
fetch('https://api.example.com/items')
.then((res) => res.json())
.then((json) => $data.set(json))
})

🛠️ 實作

1. 完成第一階段、第二階段

2. 在 src/pages/index.astro 匯入元件 DisplayButton

 ---
import Display from '../components/Display.astro'
import Button from '../components/Button'
---

<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
<Display client:load />
<Button client:load />
</body>
</html>

3. ❌ 發生錯誤

 Unable to render Button.
No valid renderer was found for the .09/blog/src/components/Button file extension.

意思是: 你試圖在 Astro 頁面中使用一個框架組件(例如 React 的 .jsx 或 .tsx),但你還沒有告訴 Astro 如何處理這種檔案

Astro 預設只懂 .astro 檔案,其他的框架(React, Vue, Svelte 等)都需要透過 Integration (整合) 手動開啟。

第一步:安裝 React 整合套件

在你的終端機執行以下指令(這會自動幫你安裝套件並修改設定檔):

npx astro add react

(當它詢問是否要繼續、更新設定檔、安裝依賴時,請一路按 y 或 Enter)

第二步:檢查設定檔 (astro.config.mjs)

執行完上述指令後,你的 astro.config.mjs 應該會自動變成這樣:

import { defineConfig } from 'astro/config'
import react from '@astrojs/react' // 1. 引入

export default defineConfig({
integrations: [react()], // 2. 啟用
})

第三步:檢查組件引用方式

在 Astro 檔案中引用 React 組件時,請確保你有加上 Client Directive(客戶端指令),否則 React 的互動功能(如點擊事件)會失效:

---
import { Button } from './Button.tsx';
---

<Button client:load />

🤔 為什麼會這樣?

Astro 的核心概念是 "Island Architecture(孤島架構)。 預設情況下,為了效能,Astro 會把所有組件都渲染成純 HTML(不含任何 JavaScript)。如果你沒安裝 React 整合包,它看到 .jsx 或 .tsx 檔案會完全不知道該如何解譯,所以才會噴出這個錯誤。

4. ✅ 成功顯示 <Display> 、 <Button>

Button 可點擊,Display 計數累加


扎實練習題

接下來的 3 個章節會陸續介紹以下三個挑戰:

  • 「購物車」挑戰: 建立一個 map 存儲購物車商品。建立一個 Astro 頁面,左邊是產品列表(點擊加入),右邊是購物車清單(即時更新數量)。
  • 「深色模式」切換: 建立一個 $isDark 的 atom,並同步到瀏覽器的 localStorage。當切換開關時,整個網站的 <html> 標籤要自動加上或移除 .dark 類名。
  • 「跨框架同步」: 如果你會兩種框架(如 React 和 Vue),嘗試寫一個 React 表單輸入文字,讓一個 Vue 元件即時顯示該文字。


留言
avatar-img
李昀瑾的沙龍
0會員
36內容數
李昀瑾的沙龍的其他內容
2026/01/17
專題二:Nano Stores —— 連結孤島的橋樑 為什麼需要它? 在 Astro 中,每個互動組件(React, Vue, Svelte)都是一個獨立的「孤島 (Island)」。 問題:如果你在 Header.tsx (React) 有一個購物車圖示,在 ProductCard.tsx 
2026/01/17
專題二:Nano Stores —— 連結孤島的橋樑 為什麼需要它? 在 Astro 中,每個互動組件(React, Vue, Svelte)都是一個獨立的「孤島 (Island)」。 問題:如果你在 Header.tsx (React) 有一個購物車圖示,在 ProductCard.tsx 
2026/01/15
🚀 專題一:Tailwind CSS 實戰開始 我們先從最能直接提升成就感的 Tailwind CSS 開始。 1. 安裝 Tailwind 在你的專案目錄執行: npx astro add tailwind (全部選 Yes,這會自動設定 astro.config.mjs 並引入指令
2026/01/15
🚀 專題一:Tailwind CSS 實戰開始 我們先從最能直接提升成就感的 Tailwind CSS 開始。 1. 安裝 Tailwind 在你的專案目錄執行: npx astro add tailwind (全部選 Yes,這會自動設定 astro.config.mjs 並引入指令
2026/01/15
✏️ 1. 利用前一章節建立的 Card.astro 組件。 ① blog.astro 匯入 Card.astro --- import BaseLayout from '../layouts/BaseLayout.astro' import PostsQuote from '../compon
2026/01/15
✏️ 1. 利用前一章節建立的 Card.astro 組件。 ① blog.astro 匯入 Card.astro --- import BaseLayout from '../layouts/BaseLayout.astro' import PostsQuote from '../compon
看更多
你可能也想看
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
網站開發專案成功的關鍵在於與客戶的有效溝通。本文分享一個成功案例,說明如何透過明確掌握專案需求、主動提供技術方案、定期回報進度、完善技術協助及建立良好客戶關係,順利完成一個中文影片學習分享網站的建置,並獲得客戶高度滿意與後續合作機會。
Thumbnail
網站開發專案成功的關鍵在於與客戶的有效溝通。本文分享一個成功案例,說明如何透過明確掌握專案需求、主動提供技術方案、定期回報進度、完善技術協助及建立良好客戶關係,順利完成一個中文影片學習分享網站的建置,並獲得客戶高度滿意與後續合作機會。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場從「網路連結 → 線下見面」的活動,我一開始其實有些猶豫,畢竟地點對我來說不近,加上平常在社群裡其實不太主動互動。 但因為主辦人西打誠意滿滿地邀請,甚至還提出補貼車資,最後我決定自費參加。現在回頭看,真的很值得! 場地很有感,氛圍超溫暖 一踏進場地就被暖黃的燈光包圍,小閣樓超舒適,還
Thumbnail
這是一場從「網路連結 → 線下見面」的活動,我一開始其實有些猶豫,畢竟地點對我來說不近,加上平常在社群裡其實不太主動互動。 但因為主辦人西打誠意滿滿地邀請,甚至還提出補貼車資,最後我決定自費參加。現在回頭看,真的很值得! 場地很有感,氛圍超溫暖 一踏進場地就被暖黃的燈光包圍,小閣樓超舒適,還
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
從實際應用中學習 Python 程式設計,提升技能並建立作品集。文章提供八個循序漸進的 Python 專案範例,涵蓋檔案操作、網路爬蟲、Web 應用、自動化腳本、數據分析、遊戲開發、API 互動及應用程式部署,並附上實戰建議及學習資源。
Thumbnail
從實際應用中學習 Python 程式設計,提升技能並建立作品集。文章提供八個循序漸進的 Python 專案範例,涵蓋檔案操作、網路爬蟲、Web 應用、自動化腳本、數據分析、遊戲開發、API 互動及應用程式部署,並附上實戰建議及學習資源。
Thumbnail
Nuxt.js 是以 Vue 為基底所建構的框架,透過 Nuxt.js,我們能夠更輕鬆地開發靜態頁面 (Static Site)、操作體驗良好的單頁式網站 (SPA)、甚至是顧及 SEO 的伺服器端渲染 (SSR) 網站。
Thumbnail
Nuxt.js 是以 Vue 為基底所建構的框架,透過 Nuxt.js,我們能夠更輕鬆地開發靜態頁面 (Static Site)、操作體驗良好的單頁式網站 (SPA)、甚至是顧及 SEO 的伺服器端渲染 (SSR) 網站。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News