Recur
開發者指南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

參數類型預設說明
typestring全部篩選產品類型:'SUBSCRIPTION''ONE_TIME''CREDITS''DONATION'
enabledbooleantrue設為 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 值

屬性類型說明
dataProduct[] | null產品列表
isLoadingboolean載入中
errorError | 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(別名)

usePlansuseProducts({ 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

On this page