Sign In
Client SDKs

React


Getting Started

First, add Rivet's Actor Client SDK to your project.

npm i @rivet-gg/actor-client --save

Generate a Actor Manager endpoint by using the rivet CLI and guide here. Then add the generated URL to your env file.

Create React App / Vite

If you're using Create React App or Vite, you can put ActorClientProvider in App.tsx.

import { Client } from "@rivet-gg/actor-client";
import { ActorClientProvider } from "@rivet-gg/actor-client/unstable-react";

export const App = () => {
  const [actorClient] = useState(() => new ActorClient({
      endpoint: process.env.VITE_APP_ACTOR_ENDPOINT,
  }));

  return (
    <ActorClientProvider client={actorClient}>
      /* your other context providers / your app  */
    </ActorClientProvider>
  );
};
App.tsx

Next.js Pages Router

If you're using Next.js Pages Router you can put ActorClientProvider in _app.tsx, or in the page where you're going to use actors.

import { Client } from "@rivet-gg/actor-client";
import { ActorClientProvider } from "@rivet-gg/actor-client/unstable-react";

export const App = ({ Component, pageProps }) => {
  const [actorClient] = useState(() => new ActorClient({
      endpoint: process.env.NEXT_PUBLIC_APP_ACTOR_ENDPOINT,
  }));

  return (
    <ActorClientProvider client={actorClient}>
      <Component {...pageProps} />
    </ActorClientProvider>
  );
};
pages/_app.tsx

Next.js App Router

If you're using Next.js app router you can put ActorClientProvider in layout.tsx, or in the layout where you're going to use actors. We recommend creating a new component for your providers as shown below, because this SDK needs to be initialized on the client side with use client directive.

'use client';
import { Client } from "@rivet-gg/actor-client";
import { ActorClientProvider } from '@rivet-gg/actor-client/unstable-react';

export function Providers({
  children,
}) {
  const [actorClient] = useState(() => new ActorClient({
      endpoint: process.env.NEXT_PUBLIC_APP_ACTOR_ENDPOINT,
  }));

  return (
    <ActorClientProvider client={actorClient}>
      {children}
    </ActorClientProvider>
  )
}

Usage

Creating an Actor

useActor is a hook that allows you to interact with actors in your React components. Pass to it a name of your actor, and optionally any other create parameters. It will connect to the actor, once the component is mounted, and disconnect when the component is unmounted.

The hook also provides the actor's state, error, and loading status. Actor created by useActor is available to that particular component tree only. If you call useActor somewhere else (even with the same arguments), it will create a new actor instance. To share the actor between components, you can use React's context or a state management library. It's safe to pass actor instance to child components as a prop, as it does not change between renders.

Optionally, if you're using TypeScript, you can pass your Actor class type to the hook to get the correct types for RPC methods.

import { useActor } from "@rivet-gg/actor-client/unstable-react";

export const MyComponent = () => {
  const [{ isLoading, error, actor }] = useActor({ name: "counter" }); 
  /* ... */
};

Remote Procedure Call (RPC)

To call any defined Remote Procedure Call (RPC) method on the actor, you can use the actor.methodName syntax. Make sure to replace methodName with the name of the method you want to call. Be aware that those methods are asynchronous and return a promise.

import { useActor } from "@rivet-gg/actor-client/unstable-react";

export const MyComponent = () => {
  const [{ isLoading, error, actor }] = useActor({ name: "counter" });

  return (
    <div>
      <button onClick={() => actor.increment()}>Increment</button> // [!code focus]
    </div>
  );
};

Events

To subscribe to actor events changes, you can use the actor.on method.

import { useActor } from "@rivet-gg/actor-client/unstable-react";

export const MyComponent = () => {
  const [{ isLoading, error, actor }] = useActor({ name: "counter" });

  useEffect(() => {
    const unsubscribe = actor.on("your event name", (event) => { 
      console.log(event); 
    }); 

    return () => { 
      unsubscribe(); 
    }; 
  }, []);
};

TypeScript

Troubleshooting

JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists

If you're getting this error, you need to add types for React. Normally React does not come with types, so you need to tell Deno to use the types from the different package.

// @deno-types=npm:@types/react
import React from "react";
your-actor.tsx

Advanced Usage

Server Driven UI

You can use the Actor RPC methods to return React components. This is done by using React Server Components paradigm.

In order to render components from your Actor, you need to ensure that your Actor extends the RscActor class from the @rivet-gg/actor package. Your RPC methods can receive props like any other React component.

import { Rpc } from "@rivet-gg/actor";
import { RscActor } from "@rivet-gg/actor/unstable-react";  

export default class ActorName extends RscActor { 

  /* ... */

  _getMessages() {
    /* 
      your code for getting messages,
      either from state or external source
    */
  }

  messages(_rpc: Rpc<this>, props: {limit: number}) {  
    const messages = this._getMessages();  

    return <ul>  // [!code focus]
      {messages.slice(0, props.limit).map((message) => (  
        <li key={message.id}>{message.text}</li>  
      ))}  // [!code focus]
    </ul> 
  } 
}
your-actor.tsx

Then, you can use the second return value of the useActor hook to use your RscActor's elements. Make sure to wrap those elements in Suspense.

import { useActor } from "@rivet-gg/actor-client/unstable-react";
import type ActorName from "../your-path-to-actor.tsx"; // replace with your actor file path

export const MyComponent = () => {
  const [
    state,
    { messages: Messages }
  ] = useActor<ActorName>({ name: "actor-name" }); 

  return (
    <Suspense> // [!code focus]
      <Messages limit={5} /> // [!code focus]
    </Suspense> 
  );
};
your-component.tsx

Experimental Features

Manual RSC update

If you need to re-render the component when the something happens in your actor, use this._updateRsc() method. This will trigger a re-render of the RSC elements in your actor. Behind the scenes, this method broadcasts an internal event __rsc that all RSC elements are listening to.

import { Rpc } from "@rivet-gg/actor";
import { RscActor } from "@rivet-gg/actor/unstable-react";

export default class ActorName extends RscActor {

  /* ... */

  someFn(_rpc: Rpc<this>) {
    this._updateRsc(); 
  }

  /* ... */

  messages(_rpc: Rpc<this>, props: {limit: number}) { 
    /* ... */
  }
}
your-actor.tsx

unstable_createActorHooks

unstable_createActorHooks is a function that allows you to create type-safe hooks for your actors. It takes an actor name and returns a hook that can be used to interact with that actor. This is useful when you want to create a custom hook that encapsulates the logic for a specific actor and its types.


import { 
  unstable_createActorHooks
} from "@rivet-gg/actor-client/unstable-react";

export const { 
  useActor, 
  useActorEventCallback, 
  useActorRsc 
} = unstable_createActorHooks("counter");
your-actor-hooks.tsx

useActor

useActor is a hook that allows you to interact with actors in your React components. Pass to it a name of your actor, and optionally any other create parameters. It will connect to the actor, once the component is mounted, and disconnect when the component is unmounted.

import { useActor } from "./your-actor-hooks";

export const MyComponent = () => {
  const [{ isLoading, error, actor }] = useActor(); 

  return (
    <div>
      <button onClick={() => actor.increment()}>Increment</button> // [!code focus]
    </div>
  );
};
your-component.tsx

useActorEventCallback

useActorEventCallback is a hook that allows you to subscribe to actor events changes. It takes an event name and a callback function that will be called when the event is triggered. You do not need to wrap the callback in useCallback as the hook will handle that for you.

import { useActorEventCallback } from "./your-actor-hooks";

export const MyComponent = ({ actor }) => {
  useActorEventCallback({ actor, event: "your event name"}, (event) => { 
    console.log(event); 
  }); 

  return null;
};
your-component.tsx

useActorRsc

useActorRsc is a hook that allows you to use React Server Components from your actor. It takes an actor instance and returns a function that can be used to render the RSC elements. Make sure to wrap those elements in Suspense. The second return value of the hook is the function to refetch the RSC elements.

import { useActorRsc } from "./your-actor-hooks";

export const MyComponent = ({ actor }) => {
  const [Messages, update] = useActorRsc({ actor, fn: 'messages' }); 

  return (
    <Suspense> // [!code focus]
      <Messages limit={5} /> // [!code focus]
    </Suspense> 
  );
};
your-component.tsx
Suggest changes to this page