@blocklet/payment-react
Version:
Reusable react components for payment kit v2
83 lines (60 loc) • 3.72 kB
Markdown
# useSubscription
`useSubscription` Hook 提供了一种使用 WebSocket 从支付服务订阅实时事件的简单方法。它处理连接、订阅和清理逻辑,让您可以专注于应用程序如何响应像 `invoice.paid` 这样的事件。
这对于创建动态用户体验至关重要,在这种体验中,UI 需要根据后端事件立即更新,而无需用户刷新页面。
## 工作原理
该 Hook 抽象了管理 WebSocket 连接的复杂性。当组件使用 `useSubscription` 时,它会与中继服务建立持久连接。然后,它会订阅您提供的特定 `channel`。该 Hook 会自动为您对通道进行命名空间化,构造一个格式为 `relay:<app-id>:<your-channel>` 的最终通道名称。
当后端服务向该通道发布事件时,Hook 的订阅对象会发出该事件,您的组件可以监听该事件。
<!-- DIAGRAM_IMAGE_START:architecture:16:9 -->

<!-- DIAGRAM_IMAGE_END -->
## 参数
该 Hook 接受一个字符串参数。
| 参数 | 类型 | 描述 | 是否必需 |
| :-------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------ | :------- |
| `channel` | `string` | 您想要监听的事件流的唯一标识符。**重要提示**:此字符串不得包含 `/`、`.` 或 `:` 等分隔符。 | 是 |
## 返回值
该 Hook 从底层的 `@arcblock/ws` 客户端库返回一个 `subscription` 对象。在建立连接期间,此对象最初可能为 `null`。
一旦连接成功,返回的对象将提供管理事件监听器的方法:
- `subscription.on(eventName, handler)`: 附加一个事件监听器。
- `subscription.off(eventName, handler)`: 移除一个事件监听器。
## 使用示例
以下是一个实时跟踪发票状态的组件示例。当后端在发票的通道上广播 `invoice.paid` 事件时,组件的 UI 会自动更新。
```tsx Real-time Invoice Status Tracker icon=logos:react
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>Invoice Status</h2>
<p>ID: {invoiceId}</p>
<p>Status: <strong>{status.toUpperCase()}</strong></p>
{status === 'pending' && <p>Waiting for payment confirmation...</p>}
{status === 'paid' && <p>Payment confirmed! Your invoice is settled.</p>}
</div>
);
}
export default InvoiceStatusTracker;
```