開發者指南React Hooks
useProducts
取得產品列表與價格的 React Hook
useProducts
useProducts 在元件掛載時自動取得產品列表,並管理 loading 和 error 狀態。
需要在 RecurProvider 內使用。
基本用法
import { useProducts } from 'recur-tw';
function PricingPage() {
const { data: products, isLoading, error } = useProducts();
if (isLoading) return <div>載入中...</div>;
if (error) return <div>載入失敗:{error.message}</div>;
return (
<div className="grid grid-cols-3 gap-4">
{products?.map((product) => (
<div key={product.id} className="border p-4 rounded">
<h3>{product.name}</h3>
<p className="text-2xl font-bold">NT${product.price}/月</p>
<p>{product.description}</p>
</div>
))}
</div>
);
}Options
| 參數 | 類型 | 預設 | 說明 |
|---|---|---|---|
type | string | 全部 | 篩選產品類型:'SUBSCRIPTION'、'ONE_TIME'、'CREDITS'、'DONATION' |
enabled | boolean | true | 設為 false 可延遲載入 |
onSuccess | (products) => void | - | 載入成功 callback |
onError | (error) => void | - | 載入失敗 callback |
篩選訂閱型產品
const { data: plans } = useProducts({ type: 'SUBSCRIPTION' });延遲載入
const [ready, setReady] = useState(false);
const { data } = useProducts({ enabled: ready });
// 之後觸發載入
<button onClick={() => setReady(true)}>顯示方案</button>Return 值
| 屬性 | 類型 | 說明 |
|---|---|---|
data | Product[] | null | 產品列表 |
isLoading | boolean | 載入中 |
error | Error | null | 錯誤物件 |
refetch | () => Promise<void> | 重新載入 |
Product 物件
interface Product {
id: string;
name: string;
slug: string;
description?: string;
price: number; // TWD 整數(如 499)
interval?: 'month' | 'year';
intervalCount?: number;
type: 'SUBSCRIPTION' | 'ONE_TIME' | 'CREDITS' | 'DONATION';
trialDays?: number;
active: boolean;
metadata?: Record<string, unknown>;
}price 是 TWD 整數,不需要除以 100。499 就是 NT$499。
usePlans(別名)
usePlans 是 useProducts({ type: 'SUBSCRIPTION' }) 的語法糖:
import { usePlans } from 'recur-tw';
// 等同於 useProducts({ type: 'SUBSCRIPTION' })
const { data: plans } = usePlans();搭配 useSubscribe
import { useProducts, useSubscribe } from 'recur-tw';
function PricingPage() {
const { data: products, isLoading } = useProducts({ type: 'SUBSCRIPTION' });
const { subscribe, isLoading: isCheckingOut } = useSubscribe();
if (isLoading) return <div>載入中...</div>;
return (
<div>
{products?.map((product) => (
<button
key={product.id}
disabled={isCheckingOut}
onClick={() => subscribe({
productId: product.id,
customerEmail: 'user@example.com',
})}
>
{product.name} - NT${product.price}/{product.interval === 'month' ? '月' : '年'}
</button>
))}
</div>
);
}Last updated on