mcpField
R
rivetkit-client-react

rivetkit-client-react

github.com/pedronauck开发64865 次安装2 天前更新
代码仓库

关于 rivetkit-client-react

rivetkit-client-react 是面向 React 应用开发者的技能,介绍如何使用 @rivetkit/react 连接 Rivet Actors,并通过 Hook 和客户端调用 Actor。

主要功能

  1. 01创建 React Actor Hook
  2. 02连接并获取 Actor
  3. 03订阅 Actor 事件
  4. 04检查连接状态
  5. 05使用 JavaScript 客户端进行 HTTP 调用

适用场景

  1. 01在 React 界面连接聊天房间 Actor
  2. 02在组件中调用计数器 Actor
  3. 03显示 Actor 连接状态
  4. 04通过客户端获取 Actor 的 HTTP 响应

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pedronauck/skills --skill rivetkit-client-react

安装后在 Claude Code 中输入/rivetkit-client-react确认已加载。

附带文件index.json

详细介绍

RivetKit React 客户端

构建通过 @rivetkit/react 连接到 Rivet Actors 的 React 应用时,请使用此技能。

入门步骤

  1. 安装 React 客户端(最新版本:2.1.0-rc.2)
    npm install @rivetkit/[email protected]
    
  2. 使用 createRivetKit() 创建 Hook,并通过 useActor() 连接。

错误处理策略

  • 默认优先采用快速失败行为。
  • 除非绝对必要,否则避免使用 try/catch。
  • 如果使用了 catch,请明确处理错误,至少记录错误。

开始使用

请参阅 React 快速入门指南 以开始使用。

安装

最简客户端

import { createRivetKit } from "@rivetkit/react";
import type { registry } from "./actors";

const { useActor } = createRivetKit<typeof registry>({
  endpoint: "https://my-namespace:[email protected]",
});

function Counter() {
  const { connection, connStatus } = useActor({ name: "counter", key: ["my-counter"] });

  if (connStatus !== "connected" || !connection) return <div>Connecting...</div>;
  return <button onClick={() => connection.increment(1)}>+</button>;
}
import { actor, setup } from "rivetkit";

export const counter = actor({
  state: { count: 0 },
  actions: {
    increment: (c, x: number) => {
      c.state.count += x;
      c.broadcast("newCount", c.state.count);
      return c.state.count;
    },
  },
});

export const registry = setup({
  use: { counter },
});

无状态与有状态

import { createRivetKit } from "@rivetkit/react";

const { useActor } = createRivetKit();

function Counter() {
  const counter = useActor({ name: "counter", key: ["my-counter"] });

  const increment = async () => {
    await counter.connection?.increment(1);
  };

  return <button onClick={increment}>+</button>;
}
// Stateless: use createClient for one-off calls (SSR or utilities)
import { createClient } from "rivetkit/client";

const client = createClient();
await client.counter.getOrCreate(["my-counter"]).increment(1);

获取 Actor

import { createRivetKit } from "@rivetkit/react";
import { createClient } from "rivetkit/client";

const { useActor } = createRivetKit();

function ChatRoom() {
  const room = useActor({ name: "chatRoom", key: ["room-42"] });
  return <div>{room.connStatus}</div>;
}

// For get/getOrCreate/create/getForId, use createClient
const client = createClient();
const handle = client.chatRoom.getOrCreate(["room-42"]);
const existing = client.chatRoom.get(["room-42"]);
const created = await client.game.create(["game-1"], { input: { mode: "ranked" } });
const byId = client.chatRoom.getForId("actor-id");
const resolvedId = await handle.resolve();

连接参数

import { createRivetKit } from "@rivetkit/react";

const { useActor } = createRivetKit();

function Chat() {
  const chat = useActor({
    name: "chatRoom",
    key: ["general"],
    params: { authToken: "jwt-token-here" },
  });

  return <div>{chat.connStatus}</div>;
}

订阅事件

import { createRivetKit } from "@rivetkit/react";

const { useActor } = createRivetKit();

function Chat() {
  const chat = useActor({ name: "chatRoom", key: ["general"] });

  chat.useEvent("message", (msg) => {
    console.log("message:", msg);
  });

  return null;
}

连接生命周期

import { createRivetKit } from "@rivetkit/react";

const { useActor } = createRivetKit();

function CounterStatus() {
  const actor = useActor({ name: "counter", key: ["my-counter"] });

  if (actor.connStatus === "connected") {
    console.log("connected");
  }

  if (actor.error) {
    console.error(actor.error);
  }

  return null;
}

底层 HTTP 和 WebSocket

使用 JavaScript 客户端访问原始 HTTP 和 WebSocket:

import { createClient } from "rivetkit/client";

const client = createClient();
const handle = client.chatRoom.getOrCreate(["general"]);

const response = await handle.fetch("history");
const history = await response.json();

const ws = await handle.webSocket("stream");
ws.addEventListener("message", (event) => {
  console.log("message:", event.data);
});
ws.send("hello");

从后端调用

在后端(Node.js/Bun)使用 JavaScript 客户端。请参阅 JavaScript 客户端文档。

错误处理

import { ActorError } from "rivetkit/client";
import { createRivetKit } from "@rivetkit/react";

const { useActor } = createRivetKit();

function Profile() {
  const actor = useActor({ name: "user", key: ["user-123"] });

  const updateUsername = async () => {
    try {
      await actor.connection?.updateUsername("ab");
    } catch (error) {
      if (error instanceof ActorError) {
        console.log(error.code, error.metadata);
      }
    }
  };

  return <button onClick={updateUsername}>Update</button>;
}

概念

键

键用于唯一标识 Actor 实例。使用复合键(数组)进行分层寻址:

import { createRivetKit } from "@rivetkit/react";
import type { registry } from "./actors";

const { useActor } = createRivetKit<typeof registry>();

function ChatRoom() {
  const room = useActor({ name: "chatRoom", key: ["org-acme", "general"] });
  return <div>{room.connStatus}</div>;
}
import { actor, setup } from "rivetkit";

export const chatRoom = actor({
  state: { messages: [] as string[] },
  actions: {
    getRoomInfo: (c) => ({ org: c.key[0], room: c.key[1] }),
  },
});

export const registry = setup({
  use: { chatRoom },
});

当 userId 包含用户数据时,不要使用字符串插值(例如 "org:${userId}")构建键。请改用数组,以防止键注入攻击。

环境变量

createRivetKit()(以及底层的 createClient() 实例)会自动读取:

  • RIVET_ENDPOINT
  • RIVET_NAMESPACE
  • RIVET_TOKEN
  • RIVET_RUNNER

如果未设置,浏览器中默认使用 window.location.origin + "/api/rivet",服务器上默认使用 http://127.0.0.1:6420。

端点格式

端点支持 URL 身份验证语法:

https://namespace:[email protected]

你也可以传入不含身份验证信息的端点,并单独提供 RIVET_NAMESPACE 和 RIVET_TOKEN。对于无服务器部署,请使用应用的 /api/rivet URL。详情请参阅端点。

API 参考

包: @rivetkit/react

需要了解客户端以外的内容?

如果你还需要了解 Rivet Actors、注册表或服务端 RivetKit,请添加主技能:

npx skills add rivet-dev/skills

然后使用 rivetkit 技能获取后端指导。

评论

支持 Markdown