Skip to content

@ahoo-wang/fetcher-react

@ahoo-wang/fetcher-react 包提供了一套全面的 React Hooks,用于封装 Fetcher HTTP 客户端生态系统。它提供了声明式数据获取、自动加载/错误状态管理、竞态条件保护、AbortController 集成、防抖查询,以及与 WowCoSecEventBusStorage 的深度集成。

安装

bash
pnpm add @ahoo-wang/fetcher-react

模块结构

mermaid
graph TB
    subgraph sg_1 ["fetcher-react modules"]
        direction TB
        CORE["core/<br>Base hooks"]
        FETCHER["fetcher/<br>Fetcher integration"]
        API["api/<br>Decorator-based API hooks"]
        WOW["wow/<br>Wow CQRS query hooks"]
        COSEC["cosec/<br>Security hooks"]
        STORAGE["storage/<br>Storage hooks"]
        EVENTBUS["eventbus/<br>Event subscription hooks"]
        DATAMON["dataMonitor/<br>Data monitor hooks"]
    end

    CORE --> FETCHER
    CORE --> API
    FETCHER --> WOW
    CORE --> COSEC
    CORE --> STORAGE
    CORE --> EVENTBUS
    CORE --> DATAMON

    style CORE fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style FETCHER fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style API fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style WOW fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style COSEC fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style STORAGE fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style EVENTBUS fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style DATAMON fill:#2d333b,stroke:#6d5dfc,color:#e6edf3

来源: packages/react/src/index.ts

核心 Hooks

usePromiseState

管理 Promise 生命周期状态的基础 Hook,不包含执行逻辑。追踪 idleloadingsuccesserror 状态。

typescript
import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';

function MyComponent() {
  const { status, loading, result, error, setSuccess, setError, setIdle } =
    usePromiseState<string>();

  return (
    <div>
      <p>Status: {status}</p>
      {loading && <p>Loading...</p>}
      {result && <p>Result: {result}</p>}
      {error && <p>Error: {error.message}</p>}
    </div>
  );
}
属性类型描述
statusPromiseStatus当前状态(idleloadingsuccesserror
loadingboolean当状态为 loading 时为 true
resultR | undefined成功解析的值
errorE | undefined拒绝时的错误
setLoading()() => void切换到加载状态
setSuccess(result)(result: R) => Promise<void>切换到成功状态并执行回调
setError(error)(error: E) => Promise<void>切换到错误状态并执行回调
setIdle()() => void重置为空闲状态

来源: packages/react/src/core/usePromiseState.ts:119-190

useExecutePromise

usePromiseState 基础上扩展了 Promise 执行功能,包括自动中止支持、通过请求 ID 实现的竞态条件保护,以及挂载安全性检查。

typescript
import { useExecutePromise } from '@ahoo-wang/fetcher-react';

function DataFetcher() {
  const { loading, result, error, execute, reset, abort } =
    useExecutePromise<string>();

  const fetch = () =>
    execute(async (abortController) => {
      const response = await fetch('/api/data', { signal: abortController.signal });
      return response.text();
    });

  return (
    <div>
      <button onClick={fetch}>Fetch</button>
      <button onClick={abort}>Cancel</button>
      {loading && <p>Loading...</p>}
      {result && <p>{result}</p>}
    </div>
  );
}
mermaid
stateDiagram-v2
    [*] --> IDLE
    IDLE --> LOADING : execute()
    LOADING --> SUCCESS : promise resolves
    LOADING --> ERROR : promise rejects
    LOADING --> IDLE : AbortError / abort()
    SUCCESS --> LOADING : execute()
    ERROR --> LOADING : execute()
    SUCCESS --> IDLE : reset()
    ERROR --> IDLE : reset()
    LOADING --> IDLE : unmount cleanup

主要特性:

  • 自动中止 -- 在开始新请求前取消任何正在进行的请求
  • 手动中止 -- 专用的 abort() 方法,支持 onAbort 回调
  • 竞态条件保护 -- 请求 ID 防止过期更新
  • 挂载安全 -- 卸载后不再更新状态

来源: packages/react/src/core/useExecutePromise.ts:210-334

useQuery

useExecutePromise 与查询参数管理相结合。支持查询参数变化时自动执行。

typescript
import { useQuery } from '@ahoo-wang/fetcher-react';

function UserComponent() {
  const { loading, result, execute, setQuery } = useQuery<UserQuery, User>({
    initialQuery: { id: '1' },
    execute: async (query) => {
      const res = await fetch(`/api/users/${query.id}`);
      return res.json();
    },
    autoExecute: true,
  });

  const handleChange = (userId: string) => {
    setQuery({ id: userId }); // auto-executes when autoExecute is true
  };

  return <div>{loading ? <p>Loading...</p> : <p>{result?.name}</p>}</div>;
}

来源: packages/react/src/core/useQuery.ts:105-173

Fetcher 集成 Hooks

useFetcher

用于 HTTP 获取操作的主要 Hook。封装了 Fetcher 客户端,提供自动中止、竞态条件保护和全面的状态管理。

mermaid
sequenceDiagram
autonumber

    participant C as Component
    participant UF as useFetcher
    participant EP as useExecutePromise
    participant F as Fetcher
    participant API as HTTP API

    C->>UF: execute(request)
    UF->>EP: execute(supplier)
    EP->>EP: Abort previous request
    EP->>EP: Create new AbortController
    UF->>F: fetcher.exchange(request, options)
    F->>API: HTTP request
    API-->>F: HTTP response
    F-->>UF: FetchExchange
    UF->>UF: exchange.extractResult()
    UF-->>C: { loading, result, error, exchange }
typescript
import { useFetcher } from '@ahoo-wang/fetcher-react';

function UserProfile({ userId }: { userId: string }) {
  const { loading, result, error, execute } = useFetcher<User>({
    resultExtractor: ResultExtractors.Json,
  });

  useEffect(() => {
    execute({ url: `/api/users/${userId}`, method: 'GET' });
  }, [userId]);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;
  return <p>{result?.name}</p>;
}
属性类型描述
exchangeFetchExchange | undefined当前/最近的 fetch 交换对象,包含请求/响应详情
execute(request)(request: FetchRequest) => Promise<void>执行 fetch 请求并自动中止之前的请求
继承自 useExecutePromise--loadingresulterrorstatusresetabort

来源: packages/react/src/fetcher/useFetcher.ts:162-226

useFetcherQuery

更高层次的 Hook,将 useFetcher 与基于 POST 的查询语义相结合。将查询参数作为请求体发送,并支持自动执行。

typescript
import { useFetcherQuery } from '@ahoo-wang/fetcher-react';

interface SearchQuery { keyword: string; limit: number; }
interface SearchResult { items: Item[]; total: number; }

function SearchComponent() {
  const { loading, result, execute, setQuery } = useFetcherQuery<SearchQuery, SearchResult>({
    url: '/api/search',
    initialQuery: { keyword: '', limit: 10 },
    autoExecute: false,
  });

  const handleSearch = (keyword: string) => {
    setQuery({ keyword, limit: 10 }); // auto-executes if autoExecute was true
  };

  return <div>{loading ? <p>Searching...</p> : <p>Found {result?.total} items</p>}</div>;
}

来源: packages/react/src/fetcher/useFetcherQuery.ts:125-192

防抖变体

对于搜索即输即查的场景,防抖变体会延迟执行直到输入稳定:

Hook基础 Hook描述
useDebouncedCallback--通过可配置的延迟对任意回调进行防抖
useDebouncedExecutePromiseuseExecutePromise防抖的 Promise 执行
useDebouncedQueryuseQuery带自动执行的防抖查询
useDebouncedFetcheruseFetcher防抖的 Fetcher 执行
useDebouncedFetcherQueryuseFetcherQuery防抖的 POST 查询

来源: packages/react/src/core/debounced/

Wow CQRS Hooks

对于使用 Wow 框架的应用程序,专用 Hook 提供了对聚合查询操作的类型化访问:

mermaid
graph LR
    subgraph sg_1 ["Wow Query Hooks"]
        direction LR
        SQ["useSingleQuery"]
        LQ["useListQuery"]
        LSTQ["useListStreamQuery"]
        PQ["usePagedQuery"]
        CQ["useCountQuery"]
    end

    SQ --> |"single state"| SNAPSHOT["SnapshotQueryClient"]
    LQ --> |"list states"| SNAPSHOT
    LSTQ --> |"SSE stream"| SNAPSHOT
    PQ --> |"paged query"| SNAPSHOT
    CQ --> |"count"| SNAPSHOT

    style SQ fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style LQ fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style LSTQ fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style PQ fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style CQ fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style SNAPSHOT fill:#161b22,stroke:#30363d,color:#e6edf3
Hook描述
useSingleQuery获取单个聚合快照
useListQuery获取聚合快照列表
useListStreamQuery以 SSE 流形式获取聚合快照
usePagedQuery获取分页聚合快照
useCountQuery统计符合条件的聚合数量

基于 Fetcher 的变体(useFetcherSingleQueryuseFetcherListQuery 等)将这些与 fetcher Hook 结合,用于直接 HTTP 集成。

来源: packages/react/src/wow/

CoSec 集成

用于使用 CoSec 认证的应用程序的安全相关 Hook:

Hook / 组件描述
useSecurity访问当前认证状态(authenticatedcurrentUser
SecurityContext向子组件提供 CoSec 安全状态的 React Context
RouteGuard路由守卫组件,重定向未认证用户
RefreshableRouteGuard在重定向前尝试刷新令牌的路由守卫

来源: packages/react/src/cosec/

Storage Hooks

Storage 包的 React 绑定:

Hook描述
useKeyStorage<T>KeyStorage<T> 实例的响应式绑定。返回 [value, setValue] 元组。存储变化时自动重新渲染。
useImmerKeyStorage<T>类似 useKeyStorage,但接受 Immer 风格的草稿变更

来源: packages/react/src/storage/

EventBus 集成

Hook描述
useEventSubscription订阅事件总线的类型化事件,组件卸载时自动清理

来源: packages/react/src/eventbus/useEventSubscription.ts

通知系统

基于通道的通知系统:

  • NotificationCenter -- 管理通知分发
  • BrowserNotificationChannel -- 显示原生浏览器通知
  • 可通过自定义 NotificationChannel 实现进行扩展

来源: packages/react/src/notification/

工具 Hooks

Hook描述
useMounted返回一个函数,用于检查组件是否仍然挂载
useLatest<T>始终持有最新值的 Ref(避免闭包过期)
useForceUpdate返回一个函数,用于强制组件重新渲染
useFullscreen管理容器元素的全屏状态

来源: packages/react/src/core/

主要导出

导出来源描述
usePromiseStatecore/Promise 生命周期的基础状态管理
useExecutePromisecore/带中止和竞态条件保护的 Promise 执行
useQuerycore/带自动执行的基于查询的异步操作
useFetcherfetcher/通过 Fetcher 客户端进行 HTTP 获取操作
useFetcherQueryfetcher/通过 Fetcher 的基于 POST 的查询
PromiseStatuscore/枚举:IDLELOADINGSUCCESSERROR
useKeyStoragestorage/响应式存储绑定
useEventSubscriptioneventbus/带自动清理的事件总线订阅

交叉引用

  • Fetcher -- useFetcheruseFetcherQuery 使用的核心 HTTP 客户端
  • Wow -- Wow 查询 Hook(useSingleQueryusePagedQuery 等)面向 Wow 聚合快照
  • CoSec -- useSecurityRouteGuard Hook 消费 CoSec 认证状态
  • Storage -- useKeyStorage 响应式绑定到 KeyStorage 实例
  • EventBus -- useEventSubscription 订阅类型化事件总线

基于 Apache License 2.0 发布。