npm package: @socketrsdk/react
Description: React hooks for Socketr — useSocketr, useChannel, usePresence, SocketrProvider
Author: Socketr
Latest version: 0.1.0

# @socketrsdk/react

React hooks for [Socketr](https://socketr.io) — real-time channels with zero boilerplate.

## Install

```bash
npm install @socketrsdk/react @socketrsdk/client
```

## Setup

Wrap your app (or the subtree that needs realtime) with `SocketrProvider`:

```tsx
import { SocketrProvider } from '@socketrsdk/react'

export default function App() {
  return (
    <SocketrProvider
      wsUrl="wss://socketr-server.fly.dev/app/pk_..."
      authProvider={async (channelName, channelData) => {
        const res = await fetch('/api/auth', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ channel_name: channelName, channel_data: channelData }),
        })
        return res.json()
      }}
    >
      <YourApp />
    </SocketrProvider>
  )
}
```

## Hooks

### `useSocketrContext()`

Access connection state from anywhere inside the provider.

```tsx
import { useSocketrContext } from '@socketrsdk/react'

function StatusBadge() {
  const { status, socketId } = useSocketrContext()
  // status: 'connecting' | 'connected' | 'reconnecting' | 'disconnected'
  return <span>{status}</span>
}
```

### `useChannel(channelName)`

Subscribe to a public channel. Returns a stable `Channel` object — register event listeners in a `useEffect`.

```tsx
import { useChannel } from '@socketrsdk/react'

function Chat() {
  const [messages, setMessages] = useState([])
  const channel = useChannel('chat-room')

  useEffect(() => {
    if (!channel) return
    const handler = (data) => setMessages(m => [...m, data])
    channel.on('message', handler)
    return () => channel.off('message', handler)
  }, [channel])

  return <MessageList messages={messages} />
}
```

### `usePresence(channelName, options)`

Subscribe to a presence channel. `members` updates automatically when people join or leave.

```tsx
import { usePresence } from '@socketrsdk/react'

function RoomMembers({ auth, channelData }) {
  const { members, memberCount } = usePresence('presence-room', { auth, channelData })

  return (
    <div>
      <span>{memberCount} online</span>
      {members.map(m => <Avatar key={m.user_id} user={m.user_info} />)}
    </div>
  )
}
```

### `useSocketr(wsUrl, options?)` — standalone (no provider)

Manage a client directly without a provider. Useful for components that own their own connection.

```tsx
import { useSocketr, useChannelWithClient } from '@socketrsdk/react'

function LiveFeed() {
  const { client, status, socketId } = useSocketr('wss://socketr-server.fly.dev/app/pk_...', {
    authProvider: async (channelName, channelData) => fetchAuth(channelName, channelData),
    onReconnecting: (attempt, delayMs) => console.log(`reconnect #${attempt} in ${delayMs}ms`),
  })

  const channel = useChannelWithClient(client, 'feed')

  useEffect(() => {
    if (!channel) return
    channel.on('post', (data) => console.log('new post', data))
  }, [channel])

  return <div>Status: {status}</div>
}
```

## API Reference

### `SocketrProvider`

| Prop | Type | Description |
|---|---|---|
| `wsUrl` | `string` | WebSocket URL — `wss://socketr-server.fly.dev/app/pk_...` |
| `authProvider` | `AuthProvider` | Called automatically for private/presence channels |
| `children` | `ReactNode` | |

### `useSocketrContext()`

Returns `{ client, status, socketId }` from the nearest `SocketrProvider`.

### `useChannel(channelName)`

Returns a `Channel | null`. Subscribes on mount, unsubscribes on unmount.

### `useChannelWithClient(client, channelName)`

Same as `useChannel` but takes an explicit client (for use with `useSocketr`).

### `usePresence(channelName, options)`

| Option | Type |
|---|---|
| `auth` | `string` — from your `/api/auth` endpoint |
| `channelData` | `string` — JSON string with `user_id` and `user_info` |

Returns `{ channel, members, memberCount }`.

### `usePresenceWithClient(client, channelName, options)`

Same as `usePresence` but takes an explicit client.

### `useSocketr(wsUrl, options?)`

| Option | Type |
|---|---|
| `authProvider` | `AuthProvider` |
| `onConnected` | `(socketId: string) => void` |
| `onReconnected` | `(socketId: string) => void` |
| `onReconnecting` | `(attempt: number, delayMs: number) => void` |
| `onDisconnected` | `() => void` |

Returns `{ client, status, connected, socketId }`.