useSubscription()
非常适合让频繁变化的资源保持最新。
使用默认的轮询订阅时,必须在 Endpoint 中设置频率,否则不会生效。
提示
useLive() 是与 useSuspense() 组合使用的更简洁写法,
用法
api/Price
import { RestEndpoint, Entity } from '@data-client/rest';
export class Price extends Entity {
symbol = '';
price = '0.0';
// ...
pk() {
return this.symbol;
}
}
export const getPrice = new RestEndpoint({
urlPrefix: 'http://test.com',
path: '/price/:symbol',
schema: Price,
pollFrequency: 5000,
});
MasterPrice
import { useSuspense, useSubscription } from '@data-client/react';
import { getPrice } from 'api/Price';
function MasterPrice({ symbol }: { symbol: string }) {
const price = useSuspense(getPrice, { symbol });
useSubscription(getPrice, { symbol });
// ...
}
行为
条件依赖
将 null 作为任意 Data Client hook 的第二个参数,表示“什么都不做”。
// todo could be undefined if id is undefined
const todo = useSubscription(TodoResource.get, id ? { id } : null);
React Native
使用 React Navigation 时,useSubscription() 会分别在获得焦点/失去焦点时订阅/取消订阅。
类型
- 类型
- 使用泛型
function useSubscription(
endpoint: ReadEndpoint,
...args: Parameters<typeof endpoint> | [null]
): void;
function useSubscription<
E extends EndpointInterface<
FetchFunction,
Schema | undefined,
undefined
>,
Args extends readonly [...Parameters<E>] | readonly [null],
>(endpoint: E, ...args: Args): void;
示例
仅在元素可见时订阅
MasterPrice.tsx
import { useIntersectionObserver } from '@uidotdev/usehooks';
import { useSuspense, useSubscription } from '@data-client/react';
import { getPrice } from 'api/Price';
function MasterPrice({ symbol }: { symbol: string }) {
const price = useSuspense(getPrice, { symbol });
const [ref, entry] = useIntersectionObserver();
// null params means don't subscribe
useSubscription(getPrice, entry?.isIntersecting ? { symbol } : null);
return <div ref={ref}>{price.price}</div>;
}
当第二个参数传入 null 时,订阅会被停用。当然,如果还有其他组件在订阅,数据更新仍会继续。
useIntersectionObserver() 使用了性能非常好的 IntersectionObserver。ref 让我们可以访问 DOM。
加密货币价格(websocket)
我们实现了自己的 StreamManager 来处理自定义的 websocket 协议。这里我们监听 useSubscription 发出的订阅/取消订阅 action,以确保只监听已渲染组件所需的更新。
探索 coin-app 示例