# React Hooks

vuer-rtc provides React hooks for seamless integration with React applications.

> See [Operations](/operations.md) for the complete reference of operation types you can use with these hooks.

## Installation

The hooks are available from the `/hooks` subpath:

```tsx

```

## GraphProvider

Wrap your app with `GraphProvider` to provide the graph context:

```tsx
function App() {
  return (
    
      
    
  );
}
```

### 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:

```tsx
function Scene() {
  const graph = useGraph();
  return (
    <>
      {Object.keys(graph.nodes).map(key => (
        
      ))}
    </>
  );
}
```

## useNode

Subscribe to a specific node by key. Re-renders only when that node changes:

```tsx
function Node({ nodeKey }: { nodeKey: string }) {
  const node = useNode(nodeKey);

  if (!node) return null;

  return (
    <mesh position={node.position}>
      <boxGeometry />
    </mesh>
  );
}
```

## useNodeProperty

Subscribe to a specific property of a node. More granular than `useNode`—only re-renders when that property changes:

```tsx
function NodePosition({ nodeKey }: { nodeKey: string }) {
  const position = useNodeProperty<[number, number, number]>(nodeKey, 'position');

  if (!position) return null;

  return <mesh position={position}><boxGeometry /></mesh>;
}
```

## useRootKey

Subscribe to the root node key. Re-renders only when the root key changes:

```tsx
function SceneRoot() {
  const rootKey = useRootKey();

  if (!rootKey) return <p>No scene loaded</p>;

  return ;
}
```

## useGraphActions

Get actions to modify the graph:

```tsx
function Node({ nodeKey }: { nodeKey: string }) {
  const node = useNode(nodeKey);
  const { edit, commit, undo, redo } = useGraphActions();

  const onDrag = (delta: [number, number, number]) => {
    edit({ ot: '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 |

## useUndoRedoShortcuts

Enables keyboard shortcuts for undo/redo:
- **Cmd/Ctrl+Z**: Undo
- **Cmd/Ctrl+Shift+Z**: Redo

```tsx
function App() {
  useUndoRedoShortcuts();

  return ;
}
```

## Full Example

```tsx

function App() {
  const wsRef = useRef(null);

  const handleSend = (msg: CRDTMessage) => {
    wsRef.current?.send(JSON.stringify(msg));
  };

  return (
    
      
    
  );
}

function SceneWithShortcuts() {
  useUndoRedoShortcuts(); // Cmd/Ctrl+Z to undo, Cmd/Ctrl+Shift+Z to redo

  return (
    <>
      
        
      
      
    </>
  );
}

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 => )}
    </>
  );
}

function UndoRedoButtons() {
  const { undo, redo } = useGraphActions();
  return (
    <div>
      <button onClick={undo}>Undo</button>
      <button onClick={redo}>Redo</button>
    </div>
  );
}
```

---

**Next:** See the [Complete Integration Guide](/integration-guide) for end-to-end examples of building collaborative applications.
