Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion content/getting-started/javascript.textile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ npm install ably

h2(#step-1). Step 1: Connect to Ably

Clients establish a connection with Ably when they instantiate an SDK. This enables them to send and receive messages in realtime across channels.
Clients establish a connection with Ably when they instantiate an SDK instance. This enables them to send and receive messages in realtime across channels.

* Open up the "dev console":https://ably.com/accounts/any/apps/any/console of your first app before instantiating your client so that you can see what happens.

Expand Down
2 changes: 1 addition & 1 deletion content/getting-started/quickstart.textile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ h2(#step-1). Add the Ably Client Library SDK
blang[javascript,nodejs].
<aside data-type='note'>
<p>
The JavaScript SDK can be used with React and React Native. We also provide a dedicated "React Hooks package.":/docs/getting-started/react
The JavaScript SDK can be used with React and React Native. We also provide a dedicated "React Hooks package.":/docs/getting-started/react-hooks
</p>
</aside>

Expand Down
248 changes: 248 additions & 0 deletions content/getting-started/react-hooks.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
---
title: React Hooks
meta_description: "The React submodule enables you to use React Hooks to connect to Ably."
languages:
- react
---

Leverage the power of Ably in your React applications using idiomatic, easy-to-use React Hooks. This package enables you to:

* Subscribe to messages on Ably "channels":/docs/channels.
* Publish messages using the channel instances provided by hooks.
* Enter the "presence set":/docs/presence-occupancy/presence on channels.
* Subscribe to presence updates on channels.
* Trigger presence updates.

The following hooks are available:

- "useChannel":#useChannel := The @useChannel@ hook subscribes to a channel and receives messages from it.
- "usePresence":#usePresence := The @usePresence@ hook enters clients into the presence set.
- "usePresenceListener":#usePresenceListener := The @usePresenceListener@ hook subscribes to presence events on a channel.
- "useConnectionStateListener":#useConnectionStateListener := The @useConnectionStateListener@ hook attaches a listener to be notified of connection state changes in the Ably client.
- "useChannelStateListener":#useChannelStateListener := The @useChannelStateListener@ hook attaches a listener to be notified of channel state changes.
- "useAbly":#useAbly := The @useAbly@ hook grants access to the Ably client instance provided by the AblyProvider context.

All hooks manage the lifecycle of Ably SDK instances for you, ensuring that you "subscribe":/docs/pub-sub#subscribe and "unsubscribe":/docs/pub-sub/advanced#unsubscribe to channels and events when your React components re-render.

h2(#install). Install

Ably JavaScript SDK versions >= 1.2.44 include React Hook functionality as standard. You don't need to install any additional packages.

```[sh]
npm install --save ably
```

<aside note-type='note'>
<p>React version 16.8 or above is required.</p>
</aside>

h2(#authenticate). Authenticate

An "API key":/docs/auth#api-keys is required to authenticate with Ably. API keys are used either to authenticate directly with Ably using "basic authentication":/docs/auth/basic, or to generate tokens for untrusted clients using "token authentication":/docs/auth/token.

"Sign up":https://ably.com/sign-up to Ably to create an API key in the "dashboard":https://ably.com/dashboard or use the "Control API":/docs/account/control-api to create an API programmatically.

<aside data-type='important'>
<p>The examples use "basic authentication":/docs/auth/basic to demonstrate usage for convenience. In your own applications, basic authentication should never be used on the client-side as it exposes your Ably API key. Instead use "token authentication.":/docs/auth/token</p>
</aside>

h2(#usage). Usage

h3(#ably-provider). Setting up the Ably Provider

<aside data-type='updated'>
<p>The @AblyProvider@ was updated in version 2.0. See the "migration guide":https://github.com/ably/ably-js/blob/main/docs/migration-guides/v2/react-hooks.md#rename-optional-id-field-to-ablyid for details on upgrading from a previous version.</p>
</aside>

Use the @AblyProvider@ component to connect to Ably. This component should be placed high up in your component tree, wrapping every component that needs to access Ably.

You can create your own client and pass it to the context provider:

```[react]
import * as Ably from 'ably';
import { AblyProvider } from 'ably/react';
import { createRoot } from 'react-dom/client';

const container = document.getElementById('root')!;
const root = createRoot(container);

const client = new Ably.Realtime({ key: '<API-key>', clientId: '<client-ID>' });

root.render(
<AblyProvider client={client}>
<App />
</AblyProvider>
);
```

h4(#multiple-clients). Multiple clients

If you need to use multiple Ably clients on the same page, you can keep your clients in separate @AblyProvider@ components. If nesting AblyProviders, you can pass a string ID for each client as a property to the provider.

```[react]
root.render(
<AblyProvider client={client} ablyId={'providerOne'}>
<AblyProvider client={client} ablyId={'providerTwo'}>
<App />
</AblyProvider>
</AblyProvider>
);
```

h3(#channel-provider). Channel Provider

<aside data-type='new'>
<p>The @ChannelProvider@ was added in version 2.0. See the "migration guide":https://github.com/ably/ably-js/blob/main/docs/migration-guides/v2/react-hooks.md#use-new-channelprovider-component for details on upgrading from a previous version.</p>
</aside>

Use the @ChannelProvider@ to define the "channels":/docs/channels you want to use in other hooks.

```[react]
<ChannelProvider channelName="{{RANDOM_CHANNEL_NAME}}">
<Component />
</ChannelProvider>
```

You can also set "channel options":/docs/channels/options in the @ChannelProvider@ component:

The following is an example of setting the "rewind":/docs/channels/options/rewind channel option:

```[react]
<ChannelProvider channelName="{{RANDOM_CHANNEL_NAME}}" options={{ params: { rewind: '1' } }}>
<Component />
</ChannelProvider>
```

Use @deriveOptions@ to set a "subscription filter":/docs/pub-sub/advanced#subscription-filters and only receive messages that satisfy a filter expression:

```[react]
const deriveOptions = { filter: 'headers.email == `"[email protected]"` || headers.company == `"domain"`' }

return (
<ChannelProvider channelName="{{RANDOM_CHANNEL_NAME}}" options={{ ... }} deriveOptions={deriveOptions}>
<Component />
</ChannelProvider>
)
```

<aside type='note'>
<p>Be aware that you can only subscribe to channels created or retrieved from a filter expression. You cannot publish to them. Use the @publish@ function of the "@useChannel@":#useChannel hook to publish messages.</p>
</aside>

h3(#useChannel). useChannel

The @useChannel@ hook enables you to "subscribe to a channel":/docs/pub-sub#subscribe and receive its messages. It can be combined with the React @useState@ hook to maintain a list of messages in your app state.

```[react]
const [messages, updateMessages] = useState([]);
const { channel } = useChannel('{{RANDOM_CHANNEL_NAME}}', (message) => {
updateMessages((prev) => [...prev, message]);
});
```

You can also filter messages by providing a message name to the @useChannel@ function:

```[react]
const { channel } = useChannel('{{RANDOM_CHANNEL_NAME}}', 'messageName', (message) => {
console.log(message);
});
```

Use the @publish@ function to publish messages to the channel:

```[react]
const { publish } = useChannel("{{RANDOM_CHANNEL_NAME}}")
publish("test-message", { text: "message text" });
```

h3(#usePresence). usePresence

<aside data-type='updated'>
<p>The @usePresence@ hook was updated in version 2.0. See the "migration guide":https://github.com/ably/ably-js/blob/main/docs/migration-guides/v2/react-hooks.md#update-usage-of-the-usepresence-hook-which-has-been-split-into-two-separate-hooks for details on upgrading from a previous version.</p>
</aside>

The @usePresence@ hook enables you to "enter the presence set":/docs/presence-occupancy/presence#member-data.

```[react]
const { updateStatus } = usePresence('{{RANDOM_CHANNEL_NAME}}');

// Optionally pass a second argument to 'usePresence' to set a client's initial member data
const { updateStatus } = usePresence('{{RANDOM_CHANNEL_NAME}}', 'initialStatus');

// The `updateStatus` function can be used to update the presence data for the current client
updateStatus('newStatus');
```

h3(#usePresenceListener). usePresenceListener

<aside data-type='new'>
<p>The @usePresenceListener@ hook was added in version 2.0. See the "migration guide":https://github.com/ably/ably-js/blob/main/docs/migration-guides/v2/react-hooks.md#update-usage-of-the-usepresence-hook-which-has-been-split-into-two-separate-hooks for details on upgrading from a previous version.</p>
</aside>

The @usePresenceListener@ hook enables you to "subscribe to presence":/docs/presence-occupancy/presence#subscribe events on a channel, notifying you when a user enters or leaves the presence set, or updates their member data.

```[react]
const { presenceData } = usePresenceListener('{{RANDOM_CHANNEL_NAME}}');

// Convert presence data to list items to render
const peers = presenceData.map((msg, index) => <li key={index}>{msg.clientId}: {msg.data}</li>);
```

<aside type='note'>
<p>Fetching presence members is executed as an effect. It will load after your component renders for the first time.</p>
</aside>

h3(#useConnectionStateListener). useConnectionStateListener

The @useConnectionStateListener@ hook enables you to attach a listener to be notified of "connection state":/docs/connect/states changes. This can be useful for detecting when a client has lost its connection.

```[react]
useConnectionStateListener((stateChange) => {
console.log(stateChange.current); // the new connection state
console.log(stateChange.previous); // the previous connection state
console.log(stateChange.reason); // if applicable, an error indicating the reason for the connection state change
});
```

You can also pass a filter to only listen for specific connection states:

```[react]
useConnectionStateListener('failed', listener); // the listener only gets called when the connection state becomes failed
useConnectionStateListener(['failed', 'suspended'], listener); // the listener only gets called when the connection state becomes failed or suspended
```

h3(#useChannelStateListener). useChannelStateListener

The @useChannelStateListener@ hook enables you to attach a listener to be notified of "channel state":/docs/channels/states changes. This can be useful for detecting when a channel error has occurred.

```[react]
useChannelStateListener((stateChange) => {
console.log(stateChange.current); // the new channel state
console.log(stateChange.previous); // the previous channel state
console.log(stateChange.reason); // if applicable, an error indicating the reason for the channel state change
});
```

Similar to "@useConnectionStateListener@":#useConnectionStateListener, you can also pass in a filter to only listen to specific channel states:

```[react]
useChannelStateListener('failed', listener); // the listener only gets called when the channel state becomes failed
useChannelStateListener(['failed', 'suspended'], listener); // the listener only gets called when the channel state becomes failed or suspended
```

h3(#useAbly). useAbly

The @useAbly@ hook enables access to the Ably client used by the "@AblyProvider@":#ably-provider context. This can be used to access APIs which aren't available through the React Hooks submodule.

```[react]
const client = useAbly();
client.authorize();
```

h2(#error-handling). Error handling

When using Ably React Hooks, you may encounter errors. The "@useChannel@":#useChannel and "@usePresence@":#usePresence hooks return connection and channel errors, enabling you to handle them in your components.

```[react]
const { connectionError, channelError } = useChannel('{{RANDOM_CHANNEL_NAME}}', messageHandler);
```
Loading