Skip to content

Commit

Permalink
Merge pull request #1446 from ably/remove-provider-options-prop
Browse files Browse the repository at this point in the history
refactor!: remove `AblyProvider` options prop
  • Loading branch information
owenpearson authored Sep 22, 2023
2 parents 6e52d0e + b5f11de commit d735e23
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 69 deletions.
8 changes: 0 additions & 8 deletions docs/react-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,6 @@ return <AblyProvider client={ably}>
</AblyProvider>
```

You may also provide the client options directly to the `AblyProvider` so that the client is created automatically. If you use this prop the client will be automatically closed when the `AblyProvider` is unmounted.

```jsx
return <AblyProvider options={options}>
{children}
</AblyProvider>
```

If you were already using multiple Ably clients in the same react application, you may pass in an optional `id` prop to the provider, which you can then pass to the hooks to specify which Ably client instance the hook should use:
```jsx
const client = new Ably.Realtime.Promise(options);
Expand Down
24 changes: 3 additions & 21 deletions docs/react.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,10 @@ The hooks are compatible with all versions of React above 16.8.0

## Usage

Start by connecting your app to Ably using the `AblyProvider` component. The options provided to the `AblyProvider` are the same options used for the Ably SDK - and requires either a `string` or an `AblyClientOptions`. You can use this configuration object to setup your API keys, or tokenAuthentication as you normally would. If you want to use the `usePresence` hook, you'll need to explicitly provide a `clientId`.
Start by connecting your app to Ably using the `AblyProvider` component. See the [`ClientOptions` documentation](https://ably.com/docs/api/realtime-sdk/types?lang=javascript) for information about what options are available when creating an Ably client. If you want to use the `usePresence` hook, you'll need to explicitly provide a `clientId`.

The `AblyProvider` should be high in your component tree, wrapping every component which needs to access Ably.


```jsx
import { AblyProvider } from "ably/react";

const options = {
key: "your-ably-api-key",
clientId: "me",
}

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

You may also create your own client and pass it into the context provider.

```jsx
import { AblyProvider } from "ably/react";
import * as Ably from "ably";
Expand Down Expand Up @@ -304,8 +286,8 @@ If you need to use multiple Ably clients on the same page, the easiest way to do

```jsx
root.render(
<AblyProvider options={options} id={'providerOne'}>
<AblyProvider options={options} id={'providerTwo'}>
<AblyProvider client={client1} id={'providerOne'}>
<AblyProvider client={client2} id={'providerTwo'}>
<App />
</AblyProvider>
</AblyProvider>
Expand Down
45 changes: 5 additions & 40 deletions src/platform/react-hooks/src/AblyProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,13 @@ const version = '1.2.44';

const canUseSymbol = typeof Symbol === 'function' && typeof Symbol.for === 'function';

/**
* Wrapper around Ably.Realtime.Promise which injects the 'react-hooks' agent
*/
export class Realtime extends Ably.Realtime.Promise {
constructor(options: string | Types.ClientOptions) {
let opts: Types.ClientOptions;

if (typeof options === 'string') {
opts = {
key: options,
} as Types.ClientOptions;
} else {
opts = { ...options };
}

(opts as any).agents = { 'react-hooks': version };

super(opts);
}
}

interface AblyProviderProps {
children?: React.ReactNode | React.ReactNode[] | null;
client?: Ably.Types.RealtimePromise;
options?: Ably.Types.ClientOptions;
id?: string;
}

type AblyContextType = React.Context<Realtime>;
type AblyContextType = React.Context<Types.RealtimePromise>;

// An object is appended to `React.createContext` which stores all contexts
// indexed by id, which is used by useAbly to find the correct context when an
Expand All @@ -52,16 +30,12 @@ export function getContext(ctxId = 'default'): AblyContextType {

let hasSentAgent = false;

export const AblyProvider = ({ client, children, options, id = 'default' }: AblyProviderProps) => {
if (!client && !options) {
throw new Error('No client or options');
}

if (client && options) {
throw new Error('Provide client or options, not both');
export const AblyProvider = ({ client, children, id = 'default' }: AblyProviderProps) => {
if (!client) {
throw new Error('AblyProvider: the `client` prop is required');
}

const realtime = useMemo(() => client || new Realtime(options as Ably.Types.ClientOptions), [client, options]);
const realtime = useMemo(() => client, [client]);

let context = getContext(id);
if (!context) {
Expand All @@ -77,14 +51,5 @@ export const AblyProvider = ({ client, children, options, id = 'default' }: Ably
}
});

// If options have been provided, the client cannot be accessed after the provider has unmounted, so close it
React.useEffect(() => {
if (options) {
return () => {
realtime.close();
};
}
}, [realtime, options]);

return <context.Provider value={realtime}>{children}</context.Provider>;
};

0 comments on commit d735e23

Please sign in to comment.