📦 使用技術
-
Expo SDK 53+
-
expo-router
-
React Hook(useState, useEffect, useLocalSearchParams)
-
可搭配 NativeWind 或
StyleSheet建 UI
🧱 專案結構範例
app/
├── _layout.tsx ← Stack 導覽容器
├── index.tsx ← 首頁
├── profile.tsx ← 資料頁
└── hooks/
└── useTimer.ts ← 自訂 Hook
1️⃣ 使用 Hook 管理狀態(單頁內)
app/index.tsx
import { useState } from 'react';
import { View, Text, Button } from 'react-native';
import { router } from 'expo-router';
export default function HomeScreen() {
const [count, setCount] = useState(0);
return (
<View style={{ padding: 30 }}>
<Text>目前計數:{count}</Text>
<Button title="加一" onPress={() => setCount(count + 1)} />
<Button title="前往 Profile 並傳值" onPress={() => router.push({
pathname: "/profile",
params: { name: "Samuel", count: count.toString() }
})} />
</View>
);
}
2️⃣ 使用 Hook 接收跨頁參數
app/profile.tsx
import { useLocalSearchParams } from 'expo-router';
import { View, Text } from 'react-native';
export default function Profile() {
const { name, count } = useLocalSearchParams();
return (
<View style={{ padding: 30 }}>
<Text>使用者名稱:{name}</Text>
<Text>你從首頁點了 {count} 次</Text>
</View>
);
}
3️⃣ 使用自訂 Hook(useTimer 範例)
hooks/useTimer.ts
import { useState, useEffect } from 'react';
export function useTimer(start = 0) {
const [seconds, setSeconds] = useState(start);
useEffect(() => {
const id = setInterval(() => setSeconds(s => s + 1), 1000);
return () => clearInterval(id);
}, []);
return seconds;
}
在頁面中使用
import { useTimer } from '../hooks/useTimer';
export default function Page() {
const seconds = useTimer();
return <Text>經過時間:{seconds} 秒</Text>;
}
4️⃣ 在 app/_layout.tsx 使用 Hook 包裝 Stack
import { Stack } from 'expo-router';
export default function Layout() {
return <Stack />;
}
🧠 常見 Hook 搭配 Expo Router 實用場景
| 功能場景 | Hook 用法 |
|---|---|
| 跨頁傳值 | router.push({ params }) + useLocalSearchParams() |
| 倒數計時 / 自動更新 | useTimer, useEffect + setInterval |
| API 拉資料 | useEffect + fetch() |
| 表單欄位處理 | useState() 管理每個欄位 |
| Theme 控制 | useColorScheme()(或 useContext) |
🔥 進階 Bonus:全站共享狀態(Global Store)
若你需要「全站共用登入狀態、購物車、語言設定」等情境,可以:
✅ 使用 zustand 建立 Hook 狀態庫
// store/user.ts
import { create } from 'zustand';
export const useUserStore = create(set => ({
name: '',
setName: (name: string) => set({ name }),
}));
// 任一頁面使用
import { useUserStore } from '../store/user';
const name = useUserStore().name;
useUserStore().setName('Samuel');
搭配 Expo Router,每一頁都能共用這個 hook 狀態,無需 props 傳遞。
📚 延伸工具(適合搭配)
| 功能 | 套件 |
|---|---|
| 表單與驗證 | react-hook-form + yup |
| 全局狀態 | zustand, jotai, recoil |
| API 請求 | swr, react-query, axios |
| BLE / 硬體 | 自訂 Hook + react-native-ble-plx |
✅ 結論
| 任務 | 建議 Hook 使用方式 |
|---|---|
| 單頁互動 | useState, useEffect |
| 多頁傳值 | router.push(), useLocalSearchParams() |
| 跨頁共享狀態 | 自訂 Hook / Zustand / Context |
| 重複邏輯抽象 | 建立 useXXX 自訂 Hook |
文章標籤
全站熱搜
