React
Room Service comes with a native React client. You should use this client instead of the @roomservice/browser
client.
Getting Started
Install the client with:
1yarn add @roomservice/react23# or45npm install --save @roomservice/react
Then, at the root of your project, add a RoomServiceProvider
. The clientOptions are the same you'd pass into the existing RoomService class:
1// app.js2import { RoomServiceProvider } from "@roomservice/react";34function App() {5 return (6 <RoomServiceProvider clientParameters={{ auth: "/my/auth/webhook" }}>7 {/* ... */}8 </RoomServiceProvider>9 );10}11
Then, from any child component, you can access Maps, Lists, and Presence keys via hooks.
Maps
While the room is attempting to connect (or failing to connect), the map
will be undefined
.
1import { useMap } from "@roomservice/react";23function CoolComponent() {4 const [map, setMap] = useMap("myRoom", "myMap");56 if (!map) return <div>Loading...</div>;78 function onChange(e) {9 setMap(map.set("name", e.target.value));10 }1112 return <input value={map.get("name")} onChange={onChange} />;13}
Lists
While the room is attempting to connect (or failing to connect), the list
will be undefined
.
1import { useList } from "@roomservice/react";23function CoolComponent() {4 const [list, setList] = useList("myRoom", "myList");56 if (!list) return <div>Loading...</div>;78 function onClick() {9 setList(list.push("new todo!"));10 }1112 return (13 <ul>14 {list.map((val, _, key) => (15 <li key={key}>{val}</li>16 ))}17 <button onClick={onClick}>Click me</button>18 </ul>19 );20}
Presence
usePresence
returns an object where each key is the user id and each value is the current value for the key.
1import { usePresence } from "@roomservice/react";23function Example() {4 const [names, setMyName] = usePresence("myRoom", "names");56 console.log(names) // { "user-123": "alice", "user-321": "berry" }78 // ...9}
When a user leaves the room, the presence key expires. So you can use this for expiring effects, like mouse cursors, presence indicators, shared highlighting effects, or anything else you might think of!
For example, here's a small mouse cursor demo:
1import { usePresence } from "@roomservice/react";23function Cursors() {4 const [positions, setMyPosition] = usePresence("myRoom", "positions");56 useEffect(() => {7 const listener = (e) => {8 setMyPosition({9 x: e.clientX,10 y: e.clientY,11 });12 };13 document.addEventListener("mousemove", listener);14 return () => document.removeEventListener("mousemove", listener);15 }, []);1617 return (18 <>19 {Object.entries(positions).map(([key, val]) => (20 <Cursor key={key} x={val.x} y={val.y} />21 ))}22 </>23 );24}
Accessing the room directly
If you'd like more control, you can always access the room directly with useRoom
. You can use this to build your own hooks and have more control over the state changes.
1import { useRoom } from "@roomservice/react"23function CoolComponent() {4 const room = useRoom("cool-room")56 if (!room) return <div>Loading...</div>78 return //...9}