Skip to content

Commit 8004d3e

Browse files
authored
Merge pull request #2534 from ably/PUB-1552/pubsub-react-start
[PUB-1552] Add Pub/Sub React getting started guide
2 parents b0f0512 + 5006227 commit 8004d3e

File tree

17 files changed

+801
-173
lines changed

17 files changed

+801
-173
lines changed

content/getting-started/javascript.textile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ npm install ably
5353

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

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

5858
* 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.
5959

content/getting-started/quickstart.textile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ h2(#step-1). Add the Ably Client Library SDK
5050
blang[javascript,nodejs].
5151
<aside data-type='note'>
5252
<p>
53-
The JavaScript SDK can be used with React and React Native. We also provide a dedicated "React Hooks package.":/docs/getting-started/react
53+
The JavaScript SDK can be used with React and React Native. We also provide a dedicated "React Hooks package.":/docs/getting-started/react-hooks
5454
</p>
5555
</aside>
5656

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
---
2+
title: React Hooks
3+
meta_description: "The React submodule enables you to use React Hooks to connect to Ably."
4+
languages:
5+
- react
6+
---
7+
8+
Leverage the power of Ably in your React applications using idiomatic, easy-to-use React Hooks. This package enables you to:
9+
10+
* Subscribe to messages on Ably "channels":/docs/channels.
11+
* Publish messages using the channel instances provided by hooks.
12+
* Enter the "presence set":/docs/presence-occupancy/presence on channels.
13+
* Subscribe to presence updates on channels.
14+
* Trigger presence updates.
15+
16+
The following hooks are available:
17+
18+
- "useChannel":#useChannel := The @useChannel@ hook subscribes to a channel and receives messages from it.
19+
- "usePresence":#usePresence := The @usePresence@ hook enters clients into the presence set.
20+
- "usePresenceListener":#usePresenceListener := The @usePresenceListener@ hook subscribes to presence events on a channel.
21+
- "useConnectionStateListener":#useConnectionStateListener := The @useConnectionStateListener@ hook attaches a listener to be notified of connection state changes in the Ably client.
22+
- "useChannelStateListener":#useChannelStateListener := The @useChannelStateListener@ hook attaches a listener to be notified of channel state changes.
23+
- "useAbly":#useAbly := The @useAbly@ hook grants access to the Ably client instance provided by the AblyProvider context.
24+
25+
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.
26+
27+
h2(#install). Install
28+
29+
Ably JavaScript SDK versions >= 1.2.44 include React Hook functionality as standard. You don't need to install any additional packages.
30+
31+
```[sh]
32+
npm install --save ably
33+
```
34+
35+
<aside note-type='note'>
36+
<p>React version 16.8 or above is required.</p>
37+
</aside>
38+
39+
h2(#authenticate). Authenticate
40+
41+
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.
42+
43+
"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.
44+
45+
<aside data-type='important'>
46+
<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>
47+
</aside>
48+
49+
h2(#usage). Usage
50+
51+
h3(#ably-provider). Setting up the Ably Provider
52+
53+
<aside data-type='updated'>
54+
<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>
55+
</aside>
56+
57+
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.
58+
59+
You can create your own client and pass it to the context provider:
60+
61+
```[react]
62+
import * as Ably from 'ably';
63+
import { AblyProvider } from 'ably/react';
64+
import { createRoot } from 'react-dom/client';
65+
66+
const container = document.getElementById('root')!;
67+
const root = createRoot(container);
68+
69+
const client = new Ably.Realtime({ key: '<API-key>', clientId: '<client-ID>' });
70+
71+
root.render(
72+
<AblyProvider client={client}>
73+
<App />
74+
</AblyProvider>
75+
);
76+
```
77+
78+
h4(#multiple-clients). Multiple clients
79+
80+
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.
81+
82+
```[react]
83+
root.render(
84+
<AblyProvider client={client} ablyId={'providerOne'}>
85+
<AblyProvider client={client} ablyId={'providerTwo'}>
86+
<App />
87+
</AblyProvider>
88+
</AblyProvider>
89+
);
90+
```
91+
92+
h3(#channel-provider). Channel Provider
93+
94+
<aside data-type='new'>
95+
<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>
96+
</aside>
97+
98+
Use the @ChannelProvider@ to define the "channels":/docs/channels you want to use in other hooks.
99+
100+
```[react]
101+
<ChannelProvider channelName="{{RANDOM_CHANNEL_NAME}}">
102+
<Component />
103+
</ChannelProvider>
104+
```
105+
106+
You can also set "channel options":/docs/channels/options in the @ChannelProvider@ component:
107+
108+
The following is an example of setting the "rewind":/docs/channels/options/rewind channel option:
109+
110+
```[react]
111+
<ChannelProvider channelName="{{RANDOM_CHANNEL_NAME}}" options={{ params: { rewind: '1' } }}>
112+
<Component />
113+
</ChannelProvider>
114+
```
115+
116+
Use @deriveOptions@ to set a "subscription filter":/docs/pub-sub/advanced#subscription-filters and only receive messages that satisfy a filter expression:
117+
118+
```[react]
119+
const deriveOptions = { filter: 'headers.email == `"[email protected]"` || headers.company == `"domain"`' }
120+
121+
return (
122+
<ChannelProvider channelName="{{RANDOM_CHANNEL_NAME}}" options={{ ... }} deriveOptions={deriveOptions}>
123+
<Component />
124+
</ChannelProvider>
125+
)
126+
```
127+
128+
<aside type='note'>
129+
<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>
130+
</aside>
131+
132+
h3(#useChannel). useChannel
133+
134+
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.
135+
136+
```[react]
137+
const [messages, updateMessages] = useState([]);
138+
const { channel } = useChannel('{{RANDOM_CHANNEL_NAME}}', (message) => {
139+
updateMessages((prev) => [...prev, message]);
140+
});
141+
```
142+
143+
You can also filter messages by providing a message name to the @useChannel@ function:
144+
145+
```[react]
146+
const { channel } = useChannel('{{RANDOM_CHANNEL_NAME}}', 'messageName', (message) => {
147+
console.log(message);
148+
});
149+
```
150+
151+
Use the @publish@ function to publish messages to the channel:
152+
153+
```[react]
154+
const { publish } = useChannel("{{RANDOM_CHANNEL_NAME}}")
155+
publish("test-message", { text: "message text" });
156+
```
157+
158+
h3(#usePresence). usePresence
159+
160+
<aside data-type='updated'>
161+
<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>
162+
</aside>
163+
164+
The @usePresence@ hook enables you to "enter the presence set":/docs/presence-occupancy/presence#member-data.
165+
166+
```[react]
167+
const { updateStatus } = usePresence('{{RANDOM_CHANNEL_NAME}}');
168+
169+
// Optionally pass a second argument to 'usePresence' to set a client's initial member data
170+
const { updateStatus } = usePresence('{{RANDOM_CHANNEL_NAME}}', 'initialStatus');
171+
172+
// The `updateStatus` function can be used to update the presence data for the current client
173+
updateStatus('newStatus');
174+
```
175+
176+
h3(#usePresenceListener). usePresenceListener
177+
178+
<aside data-type='new'>
179+
<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>
180+
</aside>
181+
182+
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.
183+
184+
```[react]
185+
const { presenceData } = usePresenceListener('{{RANDOM_CHANNEL_NAME}}');
186+
187+
// Convert presence data to list items to render
188+
const peers = presenceData.map((msg, index) => <li key={index}>{msg.clientId}: {msg.data}</li>);
189+
```
190+
191+
<aside type='note'>
192+
<p>Fetching presence members is executed as an effect. It will load after your component renders for the first time.</p>
193+
</aside>
194+
195+
h3(#useConnectionStateListener). useConnectionStateListener
196+
197+
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.
198+
199+
```[react]
200+
useConnectionStateListener((stateChange) => {
201+
console.log(stateChange.current); // the new connection state
202+
console.log(stateChange.previous); // the previous connection state
203+
console.log(stateChange.reason); // if applicable, an error indicating the reason for the connection state change
204+
});
205+
```
206+
207+
You can also pass a filter to only listen for specific connection states:
208+
209+
```[react]
210+
useConnectionStateListener('failed', listener); // the listener only gets called when the connection state becomes failed
211+
useConnectionStateListener(['failed', 'suspended'], listener); // the listener only gets called when the connection state becomes failed or suspended
212+
```
213+
214+
h3(#useChannelStateListener). useChannelStateListener
215+
216+
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.
217+
218+
```[react]
219+
useChannelStateListener((stateChange) => {
220+
console.log(stateChange.current); // the new channel state
221+
console.log(stateChange.previous); // the previous channel state
222+
console.log(stateChange.reason); // if applicable, an error indicating the reason for the channel state change
223+
});
224+
```
225+
226+
Similar to "@useConnectionStateListener@":#useConnectionStateListener, you can also pass in a filter to only listen to specific channel states:
227+
228+
```[react]
229+
useChannelStateListener('failed', listener); // the listener only gets called when the channel state becomes failed
230+
useChannelStateListener(['failed', 'suspended'], listener); // the listener only gets called when the channel state becomes failed or suspended
231+
```
232+
233+
h3(#useAbly). useAbly
234+
235+
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.
236+
237+
```[react]
238+
const client = useAbly();
239+
client.authorize();
240+
```
241+
242+
h2(#error-handling). Error handling
243+
244+
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.
245+
246+
```[react]
247+
const { connectionError, channelError } = useChannel('{{RANDOM_CHANNEL_NAME}}', messageHandler);
248+
```

0 commit comments

Comments
 (0)