# @archie/react-sdk 中文文档

规范地址：https://npmcn.com/package/%40archie/react-sdk/

版本：0\.8\.0
npm 元数据更新时间：2026-11-03T19:04:44.072Z
中文译文更新时间：2026-11-06T14:28:05.949Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40archie/react-sdk
原文对照：https://npmcn.com/package/%40archie/react-sdk/?lang=original
项目主页：https://github.com/8base-archie/archie-sdk/tree/master/packages/react-sdk#readme
源码仓库：https://github.com/8base-archie/archie-sdk

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：244 kB，6 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=18\.0\.0
- 运行依赖：0 个
- peer 依赖：react \>=18\.0\.0，@archie/js-sdk \>=0\.7\.0 \<1\.0\.0
- 首次发布：2026-03-19T04:26:19.202Z
- 最新版本发布：2026-11-03T19:04:43.907Z
- 近 30 天下载量：6390（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：19（近 12 个月 19 个）

## 中文简介

Archie BAS - 反应钩、提供者和组件

## 安装

```sh
npm install @archie/react-sdk
```

也可以使用：`pnpm add @archie/react-sdk`、`yarn add @archie/react-sdk`、`bun add @archie/react-sdk`

## README

# @archie/反应-sdk

反应钩、提供者和组件 [阿奇・巴斯](https://archie.dev/) 平台.

建于顶上 [`@archie/js-sdk`](https://npmcn.com/package/%40archie/js-sdk),这个软件包提供了与认证状态管理,声明数据获取,实时订阅,文件上传与进度跟踪,以及路由守护的完全反应反应集成.

* * *

## 目录

-   [安装](https://npmcn.com/package/%40archie/react-sdk/#readme-installation)
-   [快速启动](https://npmcn.com/package/%40archie/react-sdk/#readme-quick-start)
-   [阿尔奇提供器](https://npmcn.com/package/%40archie/react-sdk/#readme-archieprovider)
-   [钩子](https://npmcn.com/package/%40archie/react-sdk/#readme-hooks)
    -   [使用Archie客户端](https://npmcn.com/package/%40archie/react-sdk/#readme-usearchieclient)
    -   [用户](https://npmcn.com/package/%40archie/react-sdk/#readme-useauth)
    -   [使用查询](https://npmcn.com/package/%40archie/react-sdk/#readme-usequery)
    -   [组合](https://npmcn.com/package/%40archie/react-sdk/#readme-usemutation)
    -   [用户订阅](https://npmcn.com/package/%40archie/react-sdk/#readme-usesubscription)
    -   [使用文件加载](https://npmcn.com/package/%40archie/react-sdk/#readme-usefileupload)
    -   [用户](https://npmcn.com/package/%40archie/react-sdk/#readme-userest)
    -   [使用Rest查询](https://npmcn.com/package/%40archie/react-sdk/#readme-userestquery)
    -   [反应](https://npmcn.com/package/%40archie/react-sdk/#readme-userestmutation)
    -   [说明](https://npmcn.com/package/%40archie/react-sdk/#readme-usenotifications)
    -   [使用AIChat 语句](https://npmcn.com/package/%40archie/react-sdk/#readme-useaichat)
-   [构成部分](https://npmcn.com/package/%40archie/react-sdk/#readme-components)
    -   [自动守护](https://npmcn.com/package/%40archie/react-sdk/#readme-authguard)
    -   [通知行动](https://npmcn.com/package/%40archie/react-sdk/#readme-notificationaction)
-   [再出口类型](https://npmcn.com/package/%40archie/react-sdk/#readme-re-exported-types)
-   [处理错误](https://npmcn.com/package/%40archie/react-sdk/#readme-error-handling)
-   [SSR 兼容性](https://npmcn.com/package/%40archie/react-sdk/#readme-ssr-compatibility)
-   [类型脚本](https://npmcn.com/package/%40archie/react-sdk/#readme-typescript)
-   [许可证](https://npmcn.com/package/%40archie/react-sdk/#readme-license)

* * *

## 安装

```bash
npm install @archie/js-sdk @archie/react-sdk
# or
pnpm add @archie/js-sdk @archie/react-sdk
```

**同伴依赖性 :** `react >=18`, (中文(简体) ), `@archie/js-sdk`

* * *

## 快速启动

```tsx
import { createClient } from '@archie/js-sdk';
import { ArchieProvider, useAuth, useQuery, AuthGuard } from '@archie/react-sdk';

const archie = createClient({
  projectId: 'your-project-uuid',
  apiKey: 'anon your-api-key',
  apiUrl: 'https://your-project.archiecore.com',
  environment: 'master',
  retries: 3, // automatic retry with backoff (inherited from js-sdk)
  timeout: 15_000, // request timeout in ms
});

function App() {
  return (
    <ArchieProvider client={archie}>
      <AuthGuard fallback={<LoginPage />} loadingComponent={<Spinner />}>
        <Dashboard />
      </AuthGuard>
    </ArchieProvider>
  );
}

function LoginPage() {
  const { signIn } = useAuth();

  const handleSubmit = async (email: string, password: string) => {
    const { session, error } = await signIn({ email, password });
    if (error) console.error(error.message);
  };

  return <form onSubmit={/* ... */}>/* ... */</form>;
}

function Dashboard() {
  const { user, signOut } = useAuth();
  const { data, isLoading } = useQuery<{ orders: Order[] }>('{ orders { id total status } }');

  return (
    <div>
      <p>Welcome, {user?.email}</p>
      <button onClick={signOut}>Sign Out</button>
      {isLoading ? <Spinner /> : <OrderList orders={data?.orders ?? []} />}
    </div>
  );
}
```

* * *

## 阿尔奇提供器

通过上下文包装您的 React 应用程序以提供 Archie 客户端和 认证会话状态 .

```tsx
import { createClient } from '@archie/js-sdk';
import { ArchieProvider } from '@archie/react-sdk';

const archie = createClient({ projectId: '...', apiKey: 'anon ...' });

function App() {
  return (
    <ArchieProvider client={archie}>
      <MyApp />
    </ArchieProvider>
  );
}
```

**道具 :**

| Prop | 类型 | 说明 |
| --- | --- | --- |
| `client` | `ArchieClient` | 客户实例 `createClient()` |
| `children` | `ReactNode` | 儿童成分 |

**内部 :**

-   创建反应上下文 `ArchieClient` 实例
-   电话 `client.auth.waitForInit()` 挂起以恢复恒定会话
-   订阅 `onAuthStateChange` 并按上下文更新会话
-   提供 `{ client, session, isLoading }` 切入所有子钩

* * *

## 钩子

### 使用Archie客户端

返回原始数据 `ArchieClient` 举个例子 用于提供钩外的先进用例.

```tsx
const archie = useArchieClient();

// Direct access to any module
const jwks = await archie.auth.getJWKS();
```

**掷出** 如果在外边使用 `<ArchieProvider>`。 。 。 .

* * *

### 用户

完全认证状态及操作. 所有同步方法返回 `{ data/session, error }` - 他们从来不扔.

```tsx
const {
  user, // User | null
  session, // Session | null
  isLoading, // boolean — true until initial session check completes
  isAuthenticated, // boolean — shorthand for session !== null
  signIn, // (params) => Promise<{ session, error }>
  signUp, // (params) => Promise<{ data, error }>
  exchangeCode, // ({ code }) => Promise<{ session, error }> — single-use code from a trusted server; session cannot be refreshed
  signOut, // () => Promise<void>
  confirmSignUp, // (params) => Promise<{ session, error }>
  recoverPassword, // (params) => Promise<{ data, error }>
  resetPassword, // (params) => Promise<{ data, error }>
  refreshSession, // () => Promise<{ session, error }>
} = useAuth();
```

**示例 — 签名**

```tsx
function LoginForm() {
  const { signIn, isLoading } = useAuth();
  const [error, setError] = useState<string | null>(null);

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    const { session, error } = await signIn({ email, password });
    if (error) {
      setError(error.message);
    }
    // session is automatically updated in context — no manual setState needed
  };

  return (
    <form onSubmit={handleSubmit}>
      {error && <p className="error">{error}</p>}
      {/* inputs */}
      <button disabled={isLoading}>Sign In</button>
    </form>
  );
}
```

**示例 — 签名流量 :**

```tsx
const { signUp, confirmSignUp } = useAuth();

// Step 1: Register
const { data, error } = await signUp({ email, password });
// data = { userId: '...', message: 'Check your email' }

// Step 2: Confirm with code from email
const { session, error: confirmError } = await confirmSignUp({
  email,
  code: '123456',
});
```

**示例 密码回收 :**

```tsx
const { recoverPassword, resetPassword } = useAuth();

// Step 1: Request reset
await recoverPassword({ email });

// Step 2: Reset with code
await resetPassword({ email, code: '123456', newPassword: 'newPass!' });
```

所有方法都记着 `useCallback` ——安全通过为道具,而不会引起回放.

* * *

### 使用查询

声明性图表QL查询,包含缓存, Stale-while-validated, 民意测验,和自动分解.

```tsx
const { data, error, isLoading, isRefetching, refetch } = useQuery<T>(
  gql,         // GraphQL query string
  variables?,  // Record<string, unknown>
  options?,    // UseQueryOptions
);
```

**选项 :**

| 选项 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `enabled` | `boolean` | `true` | 设定 `false` 以跳过获取(有条件查询) |
| `refetchInterval` | `number` | —— 说 | 投票间隔( 毫秒) |
| `refetchOnWindowFocus` | `boolean` | `false` | 窗口重现焦点时反射 |
| `onSuccess` | `(data: T) => void` | —— 说 | 在成功获取时调用 |
| `onError` | `(error: ArchieError) => void` | —— 说 | 调用错误 |

**返回 :**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `data` | `T | null` | 查询结果 |
| `error` | `ArchieError | null` | 失败时出错 |
| `isLoading` | `boolean` | 初始负载为真 |
| `isRefetching` | `boolean` | 在背景回溯中为真 |
| `refetch` | `() => Promise<void>` | 手动触发回推 |

**行为 :**

-   **重新确认时**: 立即显示缓存数据, 在背景中反省
-   **复制**: 多个具有相同查询+可变特性的组件共享单个网络请求
-   **关于认证更改的自动回放**: 当用户的令牌更改时, 所有正在运行的查询都会自动重排
-   **无效时自动调试**:一个挂载的查询一旦其密钥失效即重新运行(例如通过 a) `useMutation` 与 `invalidateQueries`; 同一键的同步消费者仍共享一个请求
-   **最近的答复-赢**: 当键被失效时, 已经在飞行中的反应被丢弃, 而不是用模拟前数据重新油漆视图
-   **错误从不空白视图**: 失败的再验证集 `error` 但数据已经保留在屏幕上
-   **变量跟踪**: 深度比较 `JSON.stringify` ——变量变化时的回溯
-   **安保部门安全**: 无 `window` 访问时间 `refetchOnWindowFocus` 已禁用

**实例:**

```tsx
// Basic query
const { data, isLoading } = useQuery<{ users: User[] }>('{ users { id email name } }');

// With variables
const { data } = useQuery<{ user: User }>('query($id: ID!) { user(id: $id) { id email } }', {
  id: userId,
});

// Conditional query (wait for userId)
const { data } = useQuery<{ user: User }>(
  'query($id: ID!) { user(id: $id) { id email } }',
  { id: userId },
  { enabled: !!userId },
);

// Polling every 5 seconds
const { data } = useQuery<{ stats: Stats }>('{ stats { activeUsers requests } }', undefined, {
  refetchInterval: 5000,
});
```

* * *

### 组合

带有缓存的图QL突变无效 .

```tsx
const { mutate, mutateAsync, data, error, isLoading, reset } = useMutation<T>(
  gql,       // GraphQL mutation string
  options?,  // UseMutationOptions
);
```

**选项 :**

| 选项 | 类型 | 说明 |
| --- | --- | --- |
| `onSuccess` | `(data: T) => void` | 成功突变后调用 |
| `onError` | `(error: ArchieError) => void` | 调用错误 |
| `onSettled` | `() => void` | 在成功或出错后调用 |
| `invalidateQueries` | `string[]` | 查询成功后无效的子字符串 —— 每个挂载 `useQuery` 其密钥匹配反切 |

**返回 :**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `mutate` | `(vars?) => void` | 火灾和遗忘变异 |
| `mutateAsync` | `(vars?) => Promise<T | null>` | 等待结果 |
| `data` | `T | null` | 最后一个成功结果 |
| `error` | `ArchieError | null` | 上次错误 |
| `isLoading` | `boolean` | 执行时为真 |
| `reset` | `() => void` | 清除数据/误差/正在下载 |

**示例**

```tsx
const { mutate, isLoading } = useMutation<{ createUser: User }>(
  'mutation($input: CreateUserInput!) { createUser(input: $input) { id email } }',
  {
    invalidateQueries: ['users'],
    onSuccess: (data) => toast.success(`Created ${data.createUser.email}`),
  },
);

const handleCreate = () => {
  mutate({ input: { email: 'new@user.com', name: 'John' } });
};
```

> **匹配是通过子字符串**这样 `invalidateQueries: ['id']` {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}会反射每一次 包含文本的挂载查询 `id` - 每一个都是真正的网络请求 偏爱 模式特性足以命名您变异的实体。 通过了几个 模式是便宜的:整个阵列是作为一个批次应用的,因此一个查询与 其中不止一个仍然只修补过一次.

* * *

### 用户订阅

通过 WebSocket 实时 GraphQL 订阅. 订阅挂载, 未订阅挂载 .

```tsx
const { data, error, connectionState } = useSubscription<T>(
  gql,         // GraphQL subscription string
  variables?,  // Record<string, unknown>
  options?,    // UseSubscriptionOptions
);
```

**选项 :**

| 选项 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `enabled` | `boolean` | `true` | 设定 `false` 跳过订阅 |
| `onData` | `(data: T) => void` | —— 说 | 调用每个新值 |
| `onError` | `(error: ArchieError) => void` | —— 说 | 调用错误 |

**返回 :**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `data` | `T | null` | 最近订阅价值 |
| `error` | `ArchieError | null` | 上次错误 |
| `connectionState` | `ConnectionState` | `'DISCONNECTED' | 'CONNECTING' | 'CONNECTED' | 'RECONNECTING'` |

**示例**

```tsx
function LiveOrders() {
  const { data, connectionState } = useSubscription<{ orderUpdated: Order }>(
    'subscription { orderUpdated { id status total } }',
  );

  return (
    <div>
      <Badge>{connectionState}</Badge>
      {data && <OrderCard order={data.orderUpdated} />}
    </div>
  );
}
```

**生命周期 :** 重新连接由基础自动处理 `js-sdk` 实时模块(责任后退).

* * *

### 使用文件加载

带有进度跟踪的文件上传 .

```tsx
const { upload, progress, isUploading, data, error, retry, abort, reset } = useFileUpload();
```

**返回 :**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `upload` | `(file: File | Blob, opts?: FileUploadOptions) => Promise<FileUploadResult | null>` | 开始上传;解析结果,或 `null` 故障/损坏 |
| `progress` | `number` | 真正的上传进度, 0. 100( 跳出 0 到 100 不使用 XMLHttp 请求) |
| `fraction` | `number` | 进展与0.1相同 |
| `isUploading` | `boolean` | 上传时为真 |
| `data` | `FileUploadResult | null` | `{ fileId, url, filename, mimetype, size }` 成绩报告(`url` 实值 `null` 如果搜索失败) |
| `error` | `ArchieError | null` | 失败时出错 |
| `retry` | `() => Promise<FileUploadResult | null>` | 重运行最后一个 `upload()` 带有相同文件和选项 |
| `abort` | `() => void` | 在飞行中中止上传( E)`error.code` 实值 `REQUEST_ABORTED`(中文(简体) ) |
| `reset` | `() => void` | 清除全部状态 |

`FileUploadOptions`数字 : `{ filename?, contentType?, providerType? }` (文件名和内容) `File`'s; 一个平原 `Blob` 不需要类型 `contentType`) (中文(简体) ). 还有 `{ onProgress?, signal? }`。 。 。 . `error.code` 是稳定的上传代码( e)`FILE_TOO_LARGE`, (中文(简体) ), `UNSUPPORTED_FILE_TYPE`, (中文(简体) ), `STORAGE_NOT_ENABLED`, (中文(简体) ), `UPLOAD_AUTH_REQUIRED`, (中文(简体) ), `UPLOADS_DISABLED`, (中文(简体) ), `STORAGE_QUOTA_EXCEEDED`, (中文(简体) ), `REQUEST_ABORTED`, (中文(简体) ), `TIMEOUT`。浏览器(XMLHttprequest)中的进展是真实的;在节点/SSR中它跳出0到1.

**示例**

```tsx
function FileUploader() {
  const { upload, progress, isUploading, data, error, reset } = useFileUpload();

  return (
    <div>
      <input
        type="file"
        onChange={(e) => {
          const file = e.target.files?.[0];
          if (file) upload(file, { contentType: file.type, filename: file.name });
        }}
      />
      {isUploading && <ProgressBar value={progress} />}
      {data && <p>Uploaded: {data.url ?? data.fileId}</p>}
      {error && <p className="error">{error.message}</p>}
      {data && <button onClick={reset}>Upload Another</button>}
    </div>
  );
}
```

* * *

### 用户

直接返回 REST 模块,用于必须的 REST API 调用 .

```tsx
const rest = useRest();

// rest.get<T>(path, options?)
// rest.post<T>(path, body?, options?)
// rest.put<T>(path, body?, options?)
// rest.patch<T>(path, body?, options?)
// rest.delete<T>(path, options?)
```

**示例**

```tsx
function ProductActions() {
  const rest = useRest();

  const handleExport = async () => {
    const csv = await rest.get<string>('/api/products/export');
    downloadCsv(csv);
  };

  return <button onClick={handleExport}>Export CSV</button>;
}
```

* * *

### 使用Rest查询

用于获取自定义 REST 端点的请求的声明钩 .

```tsx
const { data, error, isLoading, refetch } = useRestQuery<T>(path, options?);
```

**选项** 扩展 `RestRequestOptions` (单位:千美元)`{ headers?, params?, signal? }`与 `enabled?: boolean`。 。 。 .

**返回 :**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `data` | `T | null` | 答复数据 |
| `error` | `ArchieError | null` | 失败时出错 |
| `isLoading` | `boolean` | 初始负载为真 |
| `refetch` | `() => Promise<void>` | 手动触发回推 |

**示例**

```tsx
const { data, isLoading } = useRestQuery<Product[]>('/api/products');
const { data: product } = useRestQuery<Product>(`/api/products/${id}`, { enabled: !!id });
```

* * *

### 反应

POST/PUT/PATCH/DELETE请求的必备钩.

```tsx
const { execute, data, error, isLoading, reset } = useRestMutation<T>(path, method?);
```

**参数 :**

| 参数 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `path` | `string` | —— 说 | REST 端点路径 |
| `method` | `'POST' | 'PUT' | 'PATCH' | 'DELETE'` | `'POST'` | HTTP 方法 |

**返回 :**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `execute` | `(body?, overrideOptions?: RestRequestOptions) => Promise<T | null>` | 执行请求 |
| `data` | `T | null` | 最后一个成功结果 |
| `error` | `ArchieError | null` | 上次错误 |
| `isLoading` | `boolean` | 执行时为真 |
| `reset` | `() => void` | 清除数据/误差/正在下载 |

这个 `execute` 函数接受可选的第二个参数 `overrideOptions` (单位:千美元)`RestRequestOptions`(通过自定义) `headers`, (中文(简体) ), `params`,或 `signal` 每个请求.

**示例**

```tsx
const { execute, isLoading } = useRestMutation<Product>('/api/products', 'POST');

const handleCreate = async () => {
  const product = await execute({ name: 'Widget', price: 9.99 });
  if (product) router.push(`/products/${product.id}`);
};

// With custom headers per request
await execute(payload, { headers: { 'x-idempotency-key': uuid() } });
```

* * *

### 说明

订阅可访问应用程序通知并管理读状态 。 在挂载上打开一个 WebSocket 频道, 在卸载上关闭 .

```tsx
const { user } = useAuth();
const receiverId = user?.id ?? '';

const {
  notifications,
  latest,
  unreadCount,
  isLoading,
  error,
  connectionState,
  markAsRead,
  markAllAsRead,
  refetch,
} = useNotifications(receiverId, { enabled: !!user, limit: 20 });
```

**选项 :**

| 选项 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `enabled` | `boolean` | `true` | 设定 `false` 以跳过加载和订阅( 如用户为无效) |
| `unreadOnly` | `boolean` | `false` | 初始负载只返回未读通知 |
| `limit` | `number` | —— 说 | 在初始获取中装入的最大项 |
| `onNotification` | `(n: NotificationWithSafeUrl) => void` | —— 说 | 每一份新的现场通知(例如:吐司或音响)都使用 |

**回返情况:**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `notifications` | `Notification[]` | 历史+活来者,最先来者,由: `id` |
| `latest` | `Notification | null` | 最后一次通知是现场收到的(烤面包方便) |
| `unreadCount` | `number` | 直播未读数——自动更新 |
| `isLoading` | `boolean` | 初始历史载入时为真 |
| `error` | `ArchieError | null` | 最近的操作失败出错 |
| `connectionState` | `ConnectionState` | `'CONNECTING' | 'CONNECTED' | 'DISCONNECTED' | 'RECONNECTING'` |
| `markAsRead` | `(id: string) => Promise<void>` | 标出一个通知; 乐观地更新本地状态 |
| `markAllAsRead` | `() => Promise<void>` | 标记已装入的所有通知; 对齐 `unreadCount` 使用服务器( 通常为 0) |
| `refetch` | `() => Promise<void>` | 重新装入通知历史 |

#### 无穷卷轴

`useNotifications` 页面在历史中向后, 不丢弃或复制活件 :

```tsx
const { notifications, fetchMore, hasMore, isFetchingMore, error } = useNotifications(user.id, {
  limit: 20, // page size for fetchMore()
});

// e.g. an IntersectionObserver on a sentinel at the bottom of the list.
// Gate on `!error` so a failed page doesn't drive a tight auto-retry loop
// (the hook also suppresses fetchMore internally after an error until refetch).
useEffect(() => {
  if (hasMore && !isFetchingMore && !error) void fetchMore();
}, [hasMore, isFetchingMore, error, fetchMore]);
```

-   `fetchMore()` ——加载下一个更古老的一页并附加它(dedup,最新-first). 什么时候不行 `!hasMore`,获取器已经在飞行中,钩被禁用,或者之前 `fetchMore` 错误( 调用) `refetch()` ——或更改 `receiverId`编号 :`unreadOnly` ——重试).
-   `hasMore` ——主动过滤器有更古老的记录.
-   `isFetchingMore` a 包括: `fetchMore()` 呼叫正在飞行中(驱动下方的"加载更老"指示器).

变化 `receiverId` 或者说 `unreadOnly` 从第一页重排 pagination并重播.

**示例——未读徽章的通知钟:**

```tsx
import { useAuth, useNotifications } from '@archie/react-sdk';

function NotificationBell() {
  const { user } = useAuth();
  const receiverId = user?.id ?? '';
  const { unreadCount, connectionState } = useNotifications(receiverId, { enabled: !!user });

  return (
    <button aria-label="Notifications">
      <BellIcon />
      {unreadCount > 0 && <span className="badge">{unreadCount > 99 ? '99+' : unreadCount}</span>}
      {connectionState !== 'CONNECTED' && <span className="dot reconnecting" />}
    </button>
  );
}
```

**示例——备注即读的通知列表:**

```tsx
function NotificationList() {
  const { user } = useAuth();
  const receiverId = user?.id ?? '';
  const { notifications, isLoading, unreadCount, markAsRead, markAllAsRead } = useNotifications(
    receiverId,
    { enabled: !!user, limit: 20 },
  );

  if (isLoading) return <Spinner />;

  return (
    <div>
      <header>
        <span>{unreadCount} unread</span>
        <button onClick={() => markAllAsRead()} disabled={unreadCount === 0}>
          Mark all read
        </button>
      </header>
      <ul>
        {notifications.map((n) => (
          <li
            key={n.id}
            className={n.isRead ? 'read' : 'unread'}
            onClick={() => !n.isRead && markAsRead(n.id)}
          >
            <p>{n.actionText ?? n.notificationKey}</p>
            <time>{new Date(n.createdAt).toLocaleString()}</time>
          </li>
        ))}
      </ul>
    </div>
  );
}
```

> **总是无条件叫钩子** (接钩规则). 如果没有经认证的用户,请通过 `receiverId=''` 财务报告和审定财务报表 `enabled: false` ——钩子不会加载或订阅.

> **安全说明.** 永远不要生下来 `n.actionUrl` 作为 `href` ——是不信任的服务器数据(`javascript:`, (中文(简体) ), `data:`, (中文(简体) ), `//evil.com`, (中文(简体) ), `https://user@evil.com`) (中文(简体) ). 返回行数 `useNotifications` 携带先天化的 `safeActionUrl` 字段 (`string | null`)或使用 [`NotificationAction`](https://npmcn.com/package/%40archie/react-sdk/#readme-notificationaction) 组件。 处理 `n.metadata` 财务报告和审定财务报表 `n.params` 也不值得信赖 见 [js-sdk 读取 警卫科](https://npmcn.com/package/%40archie/js-sdk/README.md#security--trust-model) 确切规则 `safeActionUrl`。 。 。 .

**`safeActionUrl` 每一行都一样.** 里面的每件东西 `notifications` (和 `latest`)是原始通知加 `safeActionUrl: string | null`。 。 。 . `actionUrl` 它本身没有受到任何影响,所以它纯粹是添加剂.

```tsx
{
  notifications.map((n) => (
    <li key={n.id}>
      {n.safeActionUrl ? (
        <a href={n.safeActionUrl} rel="noopener noreferrer">
          Open
        </a>
      ) : null}
    </li>
  ));
}
```

* * *

### 使用AIChat 语句

现场聊天Archie AI(`client.ai.stream`(原始内容存档于2012-10-12). Reste SE. 对于一发任务(摘要、分类、取出),偏好图形QL `aiChat` 与 `useMutation`。 。 。 .

```tsx
import { useAIChat } from '@archie/react-sdk';

function Assistant() {
  const { messages, send, stop, status, usage, error } = useAIChat({
    system: 'You help customers with their orders.',
    tools: [
      {
        name: 'getOrders',
        description: 'List the current user orders',
        parameters: { type: 'object', properties: { limit: { type: 'number' } } },
        execute: async ({ limit }) => fetchOrders(Number(limit ?? 5)),
      },
    ],
    metadata: { feature: 'order-assistant' },
  });
  // render messages; send('Where is my order?'); stop() aborts
}
```

-   `messages` 处于合同状态,并在答案流时进行实时更新.
-   `providerState` 从 `done` 被保留在助理消息上 并在下一个回合怀恨在心.
-   工具环: 每个 `tool_call` 运行 `tool.execute(args, { toolCall, signal })` (或 `onToolCall(call, { signal })`),其结果(字符串作为正弦,JSON的其他值;一掷变为 `isError: true`页:1 `tool` 信件和聊天会自动继续,直到 `maxSteps` 模式调用 `send()` (默认5).
-   `status`数字 : `idle` | `submitted` | `streaming` | `error`· ; `usage` 在对话中积累; `error` 是一个 `AIError` (单位:千美元)`insufficient_credits`, (中文(简体) ), `rate_limited`(中文(简体) ).
-   `stop()`, (中文(简体) ), `reset()`,一个新的 `send()` 并卸载在飞行中中止请求;被中断的转会保留其文本并放下未解答的工具调用,所以下转是有效的.
-   选项 : `model`, (中文(简体) ), `provider`, (中文(简体) ), `system`, (中文(简体) ), `tools`, (中文(简体) ), `toolChoice`, (中文(简体) ), `responseFormat`, (中文(简体) ), `reasoning`, (中文(简体) ), `maxTokens`, (中文(简体) ), `temperature`, (中文(简体) ), `metadata`, (中文(简体) ), `providerOptions`, (中文(简体) ), `initialMessages`, (中文(简体) ), `maxSteps`, (中文(简体) ), `onToolCall`, (中文(简体) ), `onFinish`, (中文(简体) ), `onError`。 。 。 .

* * *

## 构成部分

### 自动守护

基于认证状态的有条件渲染.

```tsx
<AuthGuard fallback={<LoginPage />} loadingComponent={<Spinner />} requiredRoles={['admin']}>
  <ProtectedContent />
</AuthGuard>
```

**道具 :**

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `children` | `ReactNode` | —— 说 | 授权时显示的内容 |
| `fallback` | `ReactNode` | `null` | 未经认证或未经授权时显示的内容 |
| `loadingComponent` | `ReactNode` | `null` | 会话加载时显示的内容 |
| `requiredRoles` | `string[]` | —— 说 | 用户必须至少有其中之一角色 |

**行为:**

1.  虽然 `isLoading` \* 提供 `loadingComponent`
2.  如果未经认证,则提供 `fallback`
3.  若为 `requiredRoles` 指定且用户缺少全部 ~ 渲染 `fallback`
4.  否则... 提供 `children`

**被蒙住的警卫:**

```tsx
<AuthGuard fallback={<LoginPage />}>
  <AppLayout>
    <AuthGuard requiredRoles={['admin']} fallback={<Unauthorized />}>
      <AdminPanel />
    </AuthGuard>
  </AppLayout>
</AuthGuard>
```

* * *

### 通知行动

安全地发出通知.

```tsx
import { NotificationAction } from '@archie/react-sdk';

<NotificationAction notification={n} className="btn" />
<NotificationAction notification={n}>View details</NotificationAction>
```

**道具 :**

| Prop | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `notification` | `{ actionText?, actionUrl? }` 联合国 `Notification`(中文(简体) ) | —— 说 | 标签和链接的来源 |
| `className` | `string` | —— 说 | 适用于 `<a>` (或对 `<span>` 当没有链接时) |
| `children` | `ReactNode` | `actionText` | 覆盖标签 |

**行为:**

1.  URL通过 `safeActionUrl` (单位:千美元)`https://` 或同一来源 `/path` 页:1.
2.  安全吗 `<a href rel="noopener noreferrer">`;标签是一个纯反应文本子(已逃出,从未使用 HTML).
3.  不安全或缺少 URL − 标签为 `<span>` 没有链接.
4.  没有标签... ... ...

* * *

## 再出口类型

为了方便, `@archie/react-sdk` 从 `@archie/js-sdk`,因此不需要从两个包中导入:

```tsx
import {
  // Client
  createClient,
  type ArchieClient,
  type ArchieClientOptions,

  // Auth types
  type Session,
  type User,
  type AuthSignUpParams,
  type AuthSignInParams,
  type AuthConfirmParams,
  type AuthRecoverParams,
  type AuthResetPasswordParams,
  type AuthEvent,
  type AuthEventCallback,

  // GraphQL types
  type GraphQLResponse,
  type GraphQLRequestOptions,
  type GraphQLRawRequest,

  // File types
  type FileUploadOptions,
  type FileUploadResult,
  type CsvUploadOptions,

  // Realtime types
  type Subscription,
  type SubscriptionCallbacks,
  type RealtimeEvent,
  type RealtimeChannel,
  type ConnectionState,
  type ConnectionStateCallback,

  // REST types
  type RestRequestOptions,

  // Error classes
  ArchieError,
  AuthError,
  GraphQLError,
  NetworkError,

  // Storage
  type StorageAdapter,
  BrowserLocalStorage,
  MemoryStorage,

  // Interfaces (SOLID)
  type IAuthModule,
  type IGraphQLModule,
  type IFileModule,
  type IRealtimeModule,
  type IRestModule,
  type IHttpClient,
  type Logger,
  type TokenAccessor,
} from '@archie/react-sdk';

// React-specific prop types
import type { ArchieProviderProps, AuthGuardProps } from '@archie/react-sdk';
```

* * *

## 处理错误

全体 `useAuth` 方法返回 `{ data/session, error }` - 他们从来不扔。 对于 `useQuery` 财务报告和审定财务报表 `useMutation`,错误通过 `error` 字段中的字段.

错误类来自 `@archie/js-sdk`数字 :

| 类 | 何时 |
| --- | --- |
| `AuthError` | 认证失败( 签名、 签名、 刷新) |
| `GraphQLError` | 图QL 回复错误 |
| `NetworkError` | 网络故障、 超时 |
| `ArchieError` | 所有 Archie 错误的基础类 |

```tsx
const { error } = useQuery<{ users: User[] }>('{ users { id } }');

if (error) {
  if (error instanceof AuthError) {
    // Token expired, redirect to login
  } else if (error instanceof NetworkError) {
    // Show offline indicator
  } else {
    // Show generic error
  }
}
```

* * *

## SSR 兼容性

所有钩子都是安全的:

-   没有 `window` 或者说 `document` 初始提交时的访问
-   `refetchOnWindowFocus` 检查 `typeof window` 在添加听众之前
-   `ArchieProvider` 同步初始化会话( 没有屏蔽 SSR)
-   `AuthGuard` 调制 `loadingComponent` 在未知会话时服务器渲染时

对于像Next.js这样的框架,在组件树外创建客户端:

```tsx
// lib/archie.ts
import { createClient } from '@archie/js-sdk';

export const archie = createClient({
  projectId: process.env.NEXT_PUBLIC_ARCHIE_PROJECT_ID!,
  apiKey: process.env.NEXT_PUBLIC_ARCHIE_ANON_KEY!,
});

// app/providers.tsx
('use client');
import { ArchieProvider } from '@archie/react-sdk';
import { archie } from '@/lib/archie';

export function Providers({ children }: { children: React.ReactNode }) {
  return <ArchieProvider client={archie}>{children}</ArchieProvider>;
}
```

* * *

## 高级客户端选项

`@archie/react-sdk` 继承所有高级选项 `@archie/js-sdk` 通过 `createClient()`。这些在客户端创建时被配置一次,并自动向所有钩子传播:

```tsx
import { createClient, consoleLogger } from '@archie/js-sdk';

const archie = createClient({
  projectId: 'your-project-uuid',

  // Retry & timeout
  retries: 3, // retry transient errors (429, 500, 502, 503, 504, network)
  retryDelay: 200, // initial backoff delay in ms (exponential with jitter)
  timeout: 15_000, // abort requests after 15 seconds (0 = disabled)

  // Custom fetch — for testing, proxies, or edge runtimes
  fetch: customFetchImpl,

  // Logger
  logger: consoleLogger, // or a custom Logger implementation
});
```

| 选项 | 类型 | 默认 | 说明 |
| --- | --- | --- | --- |
| `timeout` | `number` | `30000` | 请求超时以毫秒( 0 = 已禁用) |
| `retries` | `number` | `0` | 最大重试尝试瞬态错误 |
| `retryDelay` | `number` | `200` | 初始后退延迟( ms) |
| `fetch` | `typeof fetch` | `globalThis.fetch` | 自定义获取执行 |

### 健康检查

幕后客户也会曝光 `ping()`数字 :

```tsx
const archie = useArchieClient();

const isUp = await archie.ping();
```

见全 [`@archie/js-sdk` 读取](https://npmcn.com/package/%40archie/js-sdk/README.md) 关于重试行为、后退策略、超时语义和自定义取用的详细文档.

* * *

## 类型脚本

所有的钩子都是完全通用的:

```tsx
interface User {
  id: string;
  email: string;
  name: string;
}

// Typed query response
const { data } = useQuery<{ users: User[] }>('{ users { id email name } }');
//     ^? { users: User[] } | null

// Typed mutation response
const { mutateAsync } = useMutation<{ createUser: User }>('mutation ...');
const result = await mutateAsync({ input: { email: 'a@b.com' } });
//    ^? { createUser: User } | null

// Typed subscription
const { data } = useSubscription<{ orderUpdated: Order }>('subscription ...');
//     ^? { orderUpdated: Order } | null

// Typed REST
const { data } = useRestQuery<Product[]>('/api/products');
//     ^? Product[] | null
```

* * *

## 许可证

[麻省理工学院](https://npmcn.com/package/LICENSE)

## 常见问题

### @archie/react-sdk 是什么？

Archie BAS - 反应钩、提供者和组件

### 如何安装 @archie/react-sdk？

在项目目录运行 npm install @archie/react-sdk，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（\>=18\.0\.0）、@archie/js-sdk（\>=0\.7\.0 \<1\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @archie/react-sdk 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @archie/react-sdk 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @archie/react-sdk 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @archie/react-sdk 可以商用吗？

@archie/react-sdk 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @archie/react-sdk 的下载量有多少？

根据 npm 官方下载统计，@archie/react-sdk 在 2026/10/07 – 2026/11/05 这 30 天内被下载 6,390 次，日均约 213 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @archie/react-sdk 还在维护吗？

最新版本 0\.8\.0 发布于 2026/11/04（4 天前）；至今共发布 19 个版本，其中过去 12 个月发布了 19 个；首次发布于 2026/03/19。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

