跳到主要內容

useSubscription

useSubscription hook 提供了一種使用 WebSockets 從支付服務訂閱即時事件的簡單方法。它處理連線、訂閱和清理邏輯,讓您可以專注於應用程式如何對 invoice.paid 之類的事件做出反應。

這對於創建動態使用者體驗至關重要,其中 UI 需要即時回應後端事件,而無需使用者刷新頁面。

運作方式

此 hook 抽象化了管理 WebSocket 連線的複雜性。當元件使用 useSubscription 時,它會建立一個到中繼服務的持久連線。然後它會訂閱您提供的特定 channel。此 hook 會自動為您對頻道進行命名空間處理,建構一個格式為 relay:<app-id>:<your-channel> 的最終頻道名稱。

當後端服務向該頻道發布事件時,此 hook 的訂閱物件會發出該事件,您的元件可以監聽該事件。

useSubscription

參數

此 hook 接受一個字串參數。

參數類型描述必要
channelstring您想要監聽的事件流的唯一識別碼。重要提示:此字串不得包含 /.: 等分隔符。

返回值

此 hook 從底層的 @arcblock/ws 客戶端函式庫返回一個 subscription 物件。在建立連線期間,此物件最初可能為 null

一旦連線成功,返回的物件提供了管理事件監聽器的方法:

  • subscription.on(eventName, handler):附加一個事件監聽器。
  • subscription.off(eventName, handler):移除一個事件監聽器。

範例用法

這是一個即時追蹤發票狀態的元件範例。當後端在發票的頻道上廣播 invoice.paid 事件時,元件的 UI 會自動更新。

Real-time Invoice Status Tracker

tsx
import { useSubscription } from '@blocklet/payment-react';
import React, { useState, useEffect } from 'react';

/**
 * 一個顯示發票狀態的元件,並在收到 'invoice.paid' 事件時即時更新。
 */
function InvoiceStatusTracker({ invoiceId }) {
  const [status, setStatus] = useState('pending');
  // 訂閱此發票專用的頻道
  const subscription = useSubscription(invoiceId);

  useEffect(() => {
    // WebSocket 連線建立後,subscription 物件才會可用。
    if (subscription) {
      const handlePaymentSuccess = (eventData) => {
        console.log(`收到頻道 ${invoiceId} 的 'invoice.paid' 事件:`, eventData);
        // 根據事件更新元件的狀態
        setStatus('paid');
      };

      // 附加 'invoice.paid' 事件的監聽器
      subscription.on('invoice.paid', handlePaymentSuccess);

      // 在元件卸載時清理事件監聽器至關重要
      // 或在 subscription 物件變更時,以防止記憶體洩漏。
      return () => {
        subscription.off('invoice.paid', handlePaymentSuccess);
      };
    }
    // 如果 subscription 物件本身發生變化,此 effect 應該重新執行。
  }, [subscription, invoiceId]);

  return (
    <div>
      <h2>發票狀態</h2>
      <p>ID:{invoiceId}</p>
      <p>狀態:<strong>{status.toUpperCase()}</strong></p>
      {status === 'pending' && <p>等待付款確認...</p>}
      {status === 'paid' && <p>付款已確認!您的發票已結清。</p>}
    </div>
  );
}

export default InvoiceStatusTracker;