# @colyseus/react 中文文档

规范地址：https://npmcn.com/package/%40colyseus/react/

版本：0\.18\.4
npm 元数据更新时间：2026-10-03T04:48:09.591Z
中文译文更新时间：2026-11-10T12:25:24.789Z
软件包许可：未声明

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

原始 npm 页面：https://www.npmjs.com/package/%40colyseus/react
原文对照：https://npmcn.com/package/%40colyseus/react/?lang=original

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

- 包体积（解压后）：166 kB，6 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：react \>=18\.3\.1，@colyseus/sdk ^0\.18\.2，@colyseus/schema ^5\.0\.8，@colyseus/shared-types ^0\.18\.1
- 首次发布：2026-02-09T19:17:22.891Z
- 最新版本发布：2026-10-03T04:48:09.446Z
- 近 30 天下载量：2731（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：21（近 12 个月 21 个）

## 中文简介

反应钩 [科利赛](https://colyseus.io/) 多人应用.

## 安装

```sh
npm install @colyseus/react
```

也可以使用：`pnpm add @colyseus/react`、`yarn add @colyseus/react`、`bun add @colyseus/react`

## README

# @colyseus/ 反应

反应钩 [科利赛](https://colyseus.io/) 多人应用.

![](https://npmcn.com/package/%40colyseus/react/image.webp)

## 安装

```bash
npm install @colyseus/react
```

**同伴依赖性 :** `@colyseus/sdk`, (中文(简体) ), `@colyseus/schema`,以及 `react` (单位:千美元).

## 服务器侧渲染

每个钩子在服务器上都是安全的 一个房间是现场客户端 连接并且从未被串行用于水合, 所以在服务器上的钩子 仿佛无所事事 `useRoomState()` 返回时 `undefined`, (中文(简体) ), `useRoom()` 报告 `isConnecting: true`,预测钩子返回 `undefined`连接在某种效果中发生,所以客厅到达 水分补充后立即恢复.

创建连接状态而不是假设状态:

```tsx
const players = useRoomState((state) => state.players);
if (!players) return <Spinner />;   // server render + first client paint
```

货包船a `"use client"` 指令,这样您就可以从一个 Next.js App 路由器服务器组件没有构建失败 。 钩子 就像任何反应钩一样.

## 钩子

### `useRoom(callback, deps?)`

管理Colyseus房间连接的生命周期。 处理连接,断开挂载, 当依赖关系改变时重新连接 。 正确使用 React PrintMode .

```tsx
import { Client } from "@colyseus/sdk";
import { useRoom } from "@colyseus/react";

const client = new Client("ws://localhost:2567");

function Game() {
  const { room, error, isConnecting } = useRoom(
    () => client.joinOrCreate("game_room"),
  );

  if (isConnecting) return <p>Connecting...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return <GameView room={room} />;
}
```

第一个参数是返回 a 的回调 `Promise<Room>` - 任何Colyseus配对方法都有效(`joinOrCreate`, (中文(简体) ), `join`, (中文(简体) ), `create`, (中文(简体) ), `joinById`, (中文(简体) ), `consumeSeatReservation`) (中文(简体) ).

**根据依赖性变化重新连接 :**

```tsx
const { room } = useRoom(
  () => client.joinOrCreate("game_room", { level }),
  [level],
);
```

何时 `level` 更改前一个房间左边,并建立新的连接.

**有条件连接 :**

传递 falsy 值以跳过连接直到满足条件 :

```tsx
const { room } = useRoom(
  isReady ? () => client.joinOrCreate("game_room") : null,
  [isReady],
);
```

### `useRoomState(room, selector?)`

订阅 Colyseus 房间状态变化并返回不可改变的平面对象快照 。 状态树的未更改部分保留了commerds之间的偏好等同,所以当它们实际使用的数据被改变时,只重新激活组件.

```tsx
import { useRoom, useRoomState } from "@colyseus/react";

function Game() {
  const { room } = useRoom(() => client.joinOrCreate("game_room"));
  const state = useRoomState(room);

  if (!state) return <p>Waiting for state...</p>;

  return <p>Players: {state.players.size}</p>;
}
```

**使用选择器** 以订阅状态的子集 :

```tsx
const players = useRoomState(room, (state) => state.players);
```

仅读取组件 `players` 当玩家地图改变时, 将会重新回复.

### `useRoomMessage(room, type, callback)`

订阅 Colyseus 房间信息。 召回器保存在回放器中,所以它总是更新而无需重新订阅. 当房间改变或组件卸载时自动取消订阅.

```tsx
import { useRoom, useRoomMessage } from "@colyseus/react";

function Chat() {
  const { room } = useRoom(() => client.joinOrCreate("game_room"));
  const [messages, setMessages] = useState<string[]>([]);

  useRoomMessage(room, "chat", (message) => {
    setMessages((prev) => [...prev, message]);
  });

  return (
    <ul>
      {messages.map((msg, i) => <li key={i}>{msg}</li>)}
    </ul>
  );
}
```

过 `"*"` 作为所有消息类型的监听类型.

### `useLobbyRoom(callback, deps?)`

连接到 Colyseus [大厅](https://docs.colyseus.io/builtin-rooms/lobby/) 并提供了可用房间的现场更新清单。 随着房间的创建、更新和去除,清单将自动保持.

```tsx
import { Client } from "@colyseus/sdk";
import { useLobbyRoom } from "@colyseus/react";

const client = new Client("ws://localhost:2567");

function Lobby() {
  const { rooms, error, isConnecting } = useLobbyRoom(
    () => client.joinOrCreate("lobby"),
  );

  if (isConnecting) return <p>Connecting...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {rooms.map((room) => (
        <li key={room.roomId}>
          {room.name} — {room.clients}/{room.maxClients} players
        </li>
      ))}
    </ul>
  );
}
```

**返回值:**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `rooms` | `RoomAvailable<Metadata>[]` | 可用房间实况列表 |
| `room` | `Room | undefined` | 地下大厅连接 |
| `error` | `Error | undefined` | 连接出错( 如果有) |
| `isConnecting` | `boolean` | `true` 在连接大厅时 |

### `useQueueRoom(connect, consume, deps?)`

管理一个 Colyseus 匹配队列的整个生命周期:连接到排队室,跟踪组大小,接收座位预定,确认,并消耗座位加入匹配室. 把两个房间都清理干净.

```tsx
import { Client } from "@colyseus/sdk";
import { useQueueRoom } from "@colyseus/react";

const client = new Client("ws://localhost:2567");

function Matchmaking() {
  const { room, clients, isWaiting, error } = useQueueRoom(
    () => client.joinOrCreate("queue", { rank: 1200 }),
    (reservation) => client.consumeSeatReservation(reservation),
  );

  if (error) return <p>Error: {error.message}</p>;
  if (room) return <GameScreen room={room} />;
  if (isWaiting) return <p>Waiting for match... {clients} players in group</p>;
  return <p>Connecting...</p>;
}
```

第一个参数连接到队列室. 第二个论点是: `SeatReservation` 一旦找到匹配点——使用 `client.consumeSeatReservation()` 加入比赛室.

**返回值:**

| 外地 | 类型 | 说明 |
| --- | --- | --- |
| `room` | `Room | undefined` | 火柴房,一旦座椅被消耗 |
| `queue` | `Room | undefined` | 等待时的队列室( 匹配后未定义) |
| `clients` | `number` | 当前配对组中的客户数 |
| `seat` | `SeatReservation | undefined` | 座位预定,一旦收到 |
| `error` | `Error | undefined` | 连接或匹配出错 |
| `isWaiting` | `boolean` | `true` 连接到队列并等待匹配时 |

## 网码钩 (Colyseus 0.18+)

反应约束 `@colyseus/sdk` 预测工具——客户预测,调节和远程平滑. 见 [网码文件](https://docs.colyseus.io/netcode/client-prediction) 对于基本的概念.

**一条规则是:** 结构通过快照实现,运动通过预测读取实现. `useRoomState` 以补丁速率重交 **原始同步值** - 从它做位置 让你焦躁的补丁率运动。 预测值/模拟值改变每个框架,必须远离反应渲染周期:用 `predict.value(instance, field)` 在您的帧环( R3F) `useFrame`,或 `usePredictLoop` 并写入参考文献.

下面所有钩子都以两种形式存在: 独立(`useX(room, ...)`)和被捆绑(由 `createRoomContext(options)`,没有房间争论). 将预测选项通过一次 `createRoomContext({ predict: { mode: "lerp", delay: 100 } })`。 。 。 .

### `usePredict(room, options?)`

返回共享的房间 `Predict` 举个例子. `Predict.get()` 每个呼叫构造一个新实例,所以钩子会记住每个房间一个,参考点数消费者,当最后的消费者卸载时处理.

### `useInput(room, options?)`

回到房间 `InputHandle` (单位:千美元)`room.input()` ——一能,每室稳定. 阶段字段开始 `input.data`,则 `input.send()` 每一固定步骤 `usePredictLoop` 调用.

### `usePredictLoop(room, onSteps, options?)`

拥有每帧驱动程序: 呼叫 `predict.tick(now)` 每帧一次,然后将到期的固定步骤数交给您——相位+准确发送回调内的许多输入("读取前发送"). 默认它会自己运行 `requestAnimationFrame`; 与 `{ external: true }` 它返回一个 `drive(now?)` 函数从您已有的框架循环调用 :

```tsx
// React Three Fiber — drive at an early priority so ticks precede reads:
const drive = usePredictLoop(onSteps, { external: true });
useFrame(() => drive(), -1);
```

### `useReconciler(room, select, options)`

积极预测你控制的实体—— `predict.reconciler()` 处理的生命周期:等待实体产出(`select: (state, room) => instance`),如果服务器替换实例,则重新创建控制器,并在卸载上处理. `options.input` 默认为房间的把手.

```tsx
const me = useReconciler(
  (state, room) => state.players.get(room.sessionId),
  { step: (ctx, p, cmd) => applyInput(p, cmd, ctx.dt), smoothing: 15, snap: 5 },
);
```

### `useAttachAll(room, key, config, deps?)`

被动平滑为根态收藏—— `predict.attachAll()` 作为一种效果,脱去在卸载上。 在单独的调用中附加角字段 :

```tsx
useAttachAll("players", { mode: "lerp", fields: ["x", "y", "z"] });
useAttachAll("players", { mode: "lerp", fields: ["heading"], angle: true });
```

### `useEventChannel(room, options)`

乐观事件频道—— `predict.defineEvent()` 以倾覆而未登起者发誓, **加反应**:调用组件在预测/确认/弹出/未预测上重新调用,所以旗形的引出工作以平面渲染码:

```tsx
const pickups = useEventChannel({
  confirmOn: { collection: "items", field: "alive", equals: false },
});
const hidden = !item.alive || pickups?.has(id);
```

### `useEntityInstance(room, select)` 编号 : `useSessionEntity(room, collectionKey)`

选择一个 **已解码的计划实例** (Prectt APIs 键关闭),只有当其身份变化时才会重新发回——从不在字段更新上发回. `useSessionEntity` 常见情况: 由 `sessionId`。 。 。 .

### `getSchemaInstance(snapshot)`

桥梁 `useRoomState` 将快照折回解码实例中 `predict.value()` 阅读您从快照列表中获取的实体:

```tsx
const source = getSchemaInstance(playerSnapshot);
useFrame(() => { ref.current.position.x = predict.value(source, "x"); });
```

### `useInputBuffer()`

这个 ["缓冲,然后消耗"](https://docs.colyseus.io/netcode/recipes#taps-between-steps-buffer-then-consume) 作为钩子的输入食谱 : `press()` 在事件处理器中, `consume()` 在发送回路中,一个水龙头在精确的固定步骤上降落——在0步框架上从未丢失,在多步框架上从未加倍.

完整的实例(R3F + 预测 + 远程麻黄),见 [r3f-lobby-car-原型](https://github.com/endel/r3f-lobby-car-prototype)。 。 。 .

## 背景情况

### `createRoomContext()`

创建一组钩子和一个 `RoomProvider` 组件,共享一个跨React调和器边界的单室连接(如DOM + React Three Fiber). 房间被储存在一个封闭的外置商店,而不是反应上下文,因此钩子在任何导入它们的调和树上工作.

```tsx
import { Client } from "@colyseus/sdk";
import { createRoomContext } from "@colyseus/react";

const client = new Client("ws://localhost:2567");

const { RoomProvider, useRoom, useRoomState } = createRoomContext();
```

**包装您的应用程序 `RoomProvider`数字 :**

```tsx
function App() {
  return (
    <RoomProvider connect={() => client.joinOrCreate("game_room")}>
      <UI />
      <Canvas>
        <GameScene />
      </Canvas>
    </RoomProvider>
  );
}
```

`RoomProvider` 接受一个 `connect` 调用( 与独立 `useRoom` 钩子)和可选 `deps` 阵列。 传递一个 falsy 值到 `connect` 推迟连接.

**使用任意组件中的钩子——DOM或R3F:**

```tsx
function UI() {
  const { room, error, isConnecting } = useRoom();
  const players = useRoomState((state) => state.players);

  if (isConnecting) return <p>Connecting...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return <p>Players: {players?.size}</p>;
}
```

回来的 `useRoom()` 财务报告和审定财务报表 `useRoomState(selector?)` 工作与独立的钩子相同,但不要要求你通过房间作为辩论.

### `createLobbyContext()`

创建一个 `LobbyProvider` 财务报告和审定财务报表 `useLobby` 在您的应用软件上分享大厅室数据的钩子——当您需要房间元数据时, 不仅在大厅屏幕上, 喜欢 `createRoomContext`,它使用一个闭合镜外商店,所以钩子可以跨越调和器边界工作.

```tsx
import { Client } from "@colyseus/sdk";
import { createLobbyContext, createRoomContext } from "@colyseus/react";

const client = new Client("ws://localhost:2567");

const { LobbyProvider, useLobby } = createLobbyContext<MyMetadata>();
const { RoomProvider, useRoom, useRoomState } = createRoomContext();
```

**包装您的应用程序 `LobbyProvider` (可与 `RoomProvider`:**

```tsx
function App() {
  return (
    <LobbyProvider connect={() => client.joinOrCreate("lobby")}>
      <RoomProvider connect={() => client.joinOrCreate("game_room")}>
        <UI />
        <Canvas>
          <GameScene />
        </Canvas>
      </RoomProvider>
    </LobbyProvider>
  );
}
```

`LobbyProvider` 接受一个 `connect` 回调( 和 `useLobbyRoom`)和可选 `deps` 阵列。 大厅连接独立于游戏室.

**从任何组件访问大厅数据——甚至游戏深处:**

```tsx
function RoomBrowser() {
  const { rooms, error, isConnecting } = useLobby();

  if (isConnecting) return <p>Loading rooms...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {rooms.map((room) => (
        <li key={room.roomId}>
          {room.metadata.displayName} — {room.clients}/{room.maxClients}
        </li>
      ))}
    </ul>
  );
}
```

回来的 `useLobby()` 钩子提供与 `useLobbyRoom` (单位:千美元)`rooms`, (中文(简体) ), `room`, (中文(简体) ), `error`, (中文(简体) ), `isConnecting`) (中文(简体) ).

## 贷项

灵感和以前的工作 [@ pedr0fontoura (英语)](https://github.com/pedr0fontoura) —— 说 [使用密码](https://github.com/pedr0fontoura/use-colyseus/)。 。 。 . 重写和新建 `useRoomState()` (单位:千美元) [@FTWinston (英语)](https://github.com/FTWinston)。 。 。 .

## 常见问题

### @colyseus/react 是什么？

反应钩 科利赛 多人应用\.

### 如何安装 @colyseus/react？

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

### @colyseus/react 支持 TypeScript 吗？

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

### @colyseus/react 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @colyseus/react 可以商用吗？

@colyseus/react 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @colyseus/react 的下载量有多少？

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

### @colyseus/react 还在维护吗？

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

