React Hooks
vuer-rtc provides React hooks for seamless integration with React applications.
Installation
The hooks are available from the /hooks subpath:
import { GraphProvider, useGraph, useNode, useGraphActions } from '@vuer-ai/vuer-rtc/hooks';GraphProvider
Wrap your app with GraphProvider to provide the graph context:
function App() {
return (
<GraphProvider sessionId="my-session" onSend={sendToServer}>
<Scene />
</GraphProvider>
);
}Props
| Prop | Type | Description |
|---|---|---|
sessionId | string | Unique session identifier |
onSend | (msg: CRDTMessage) => void | Callback when a message is ready to send |
useGraph
Get the current graph state:
function Scene() {
const graph = useGraph();
return (
<>
{Object.keys(graph.nodes).map(key => (
<Node key={key} nodeKey={key} />
))}
</>
);
}useNode
Subscribe to a specific node by key. Re-renders only when that node changes:
function Node({ nodeKey }: { nodeKey: string }) {
const node = useNode(nodeKey);
if (!node) return null;
return (
<mesh position={node.position}>
<boxGeometry />
</mesh>
);
}useGraphActions
Get actions to modify the graph:
function Node({ nodeKey }: { nodeKey: string }) {
const node = useNode(nodeKey);
const { edit, commit, undo, redo } = useGraphActions();
const onDrag = (delta: [number, number, number]) => {
edit({ otype: 'vector3.add', key: nodeKey, path: 'position', value: delta });
};
const onDragEnd = () => {
commit(`Move ${node?.name}`);
};
if (!node) return null;
return <mesh position={node.position} onDrag={onDrag} onDragEnd={onDragEnd} />;
}Available Actions
| Action | Signature | Description |
|---|---|---|
edit | (op: Operation) => void | Add operation to edit buffer (uncommitted) |
commit | (description?: string) => void | Commit edits as a single message |
cancelEdits | () => void | Discard uncommitted edits |
undo | () => void | Undo last committed message |
redo | () => void | Redo last undone message |
receive | (msg: CRDTMessage) => void | Process incoming remote message |
Full Example
import { GraphProvider, useGraph, useNode, useGraphActions } from '@vuer-ai/vuer-rtc/hooks';
function App() {
const wsRef = useRef<WebSocket | null>(null);
const handleSend = (msg: CRDTMessage) => {
wsRef.current?.send(JSON.stringify(msg));
};
return (
<GraphProvider sessionId="user-123" onSend={handleSend}>
<Canvas>
<Scene />
</Canvas>
<UndoRedoButtons />
</GraphProvider>
);
}
function Scene() {
const graph = useGraph();
const { receive } = useGraphActions();
// Handle incoming messages
useEffect(() => {
const ws = new WebSocket('wss://server/room');
ws.onmessage = (e) => receive(JSON.parse(e.data));
return () => ws.close();
}, [receive]);
return (
<>
{Object.keys(graph.nodes)
.filter(k => !graph.nodes[k].deletedAt)
.map(key => <Node key={key} nodeKey={key} />)}
</>
);
}
function UndoRedoButtons() {
const { undo, redo } = useGraphActions();
return (
<div>
<button onClick={undo}>Undo</button>
<button onClick={redo}>Redo</button>
</div>
);
}