📦 使用技術

  • Expo SDK 53+

  • expo-router

  • React Hook(useState, useEffect, useLocalSearchParams)

  • 可搭配 NativeWindStyleSheet 建 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

 

文章標籤
全站熱搜
創作者介紹
創作者 liusming 的頭像
liusming

劉老師的跨域創想工坊

liusming 發表在 痞客邦 留言(0) 人氣(6)