---
id: client
sidebar_position: 5
title: Client
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

Stream Chat for React Native uses the [Stream Chat client](https://github.com/GetStream/stream-chat-js) to connect to and communicate with the Stream API.

The full [JavaScript client docs](https://getstream.io/chat/docs/javascript/?language=javascript) should be referenced for detailed information on directly using the client.

## Setup

To interact with the Stream Chat API you must create a client instance and connect to the API, usually as an authenticated user.

### Instantiation

The Stream Chat client, `StreamChat` is a dependency of `stream-chat-react-native-ghn` and can be imported from `stream-chat`.
To create a client instance you can call `getInstance` on the client and provide and api key.

```ts
import { StreamChat } from 'stream-chat'; 

const client = StreamChat.getInstance('api_key');
```

:::caution

**Usage of `StreamChat.getInstance()` available since stream-chat@2.12.0.**
<br />
This new Singleton pattern allows you to instantiate a unique StreamChat client, i.e create a StreamChat instance and retrieve it wherever you need it on your app to perform API calls.
After calling it once, any following <code>getInstance</code> call will return the initial StreamChat instance.
This will prevent you from accidentally creating multiple StreamChat instances, opening multiple WebSockets, and driving up your concurrent connections unnecessarily.
<br /><br />

Stream Chat is backward compatible. Users can continue using <code>new StreamChat()</code> if desired.
<br />

```ts
const client = new StreamChat('api_key');
```

Calling <code>new StreamChat()</code> repeatedly will create new copies of the client and in turn new WebSocket connections when <code>connectUser</code> is called.
If you are using <code>new StreamChat()</code> you need to be vigilant about your use to ensure you are not creating multiple WebSocket connections unnecessarily. 

:::

### Connecting a User

To connect a user a the `connectUser` function should be called and provided with the user object and `user_token`.
The `user_token` is typically sent from your back end when a user is authenticated.

```ts
await client.connectUser( 
    { 
        id: 'testUser', 
        name: 'Test User', 
    }, 
    'user_token',
); 
```

It is recommended to not repeatedly call `connectUser` unnecessarily, multiple calls to `connectUser` will result in warnings, and attempting to call `connectUser` before disconnecting a current user will throw an Error.

## UI Components

The Stream Chat for React Native UI components handle most interactions with the client for you after connecting with an authenticated user.

### Providing the Client to the UI

To provide the the client to the UI components you simply provide the client instance as the prop `client` to the `Chat` component. 

```tsx
import { StreamChat } from 'stream-chat'; 
import { Chat } from 'stream-chat-react-native-ghn';

const client = StreamChat.getInstance('api_key');

export const Screen = () =>
  <Chat client={client}>
    {/** App components */}
  </Chat>
```

The Stream Chat for React Native UI components then handle interacting with the client internally by accessing the client via [`context`](https://reactjs.org/docs/context.html).

:::note

If you are customizing certain components or functionality you may have to interact with the client as well.
You can access the client provided to the `Chat` component internally via the `useChatContext`.
<br />

```ts
import { useChatContext } from 'stream-chat-react-native-ghn';

const { client } = useChatContext();
```

:::

### Using UI Functions

The UI provides a number of functions that interact with the client while keeping the UI state in sync using `context`.
The [contexts section](../contexts/attachment_picker_context.mdx) details what functions are accessible.
When customizing your application you should ensure you are utilizing the correct functions to keep the UI state up to date.

The `sendMessage` function for instance, provided by `useMessageInputContext`, is not the same as the `sendMessage` function found directly on a `channel` in the client.
Therefore calling `channel.sendMessage(messageData)` will not result in a message optimistically showing in the UI, or a failed send state, instead the message will not show until it is returned by the server.

:::caution

You should not assume any function directly called on the client will result in a UI update.
The UI state is managed internally by the components and `context`, most client interactions require an event returned by the server to update the UI.

:::

## Accessing the Client Instance

There are multiple ways to access the client instance throughout your application.
[As mentioned](#providing-the-client-to-the-ui) you can access the `client` via `useChatContext` when inside the `Chat` component.
This works well if you can wrap your entire application in a single `Chat` component and have the `StreamChat` instance provided throughout your app via the internal `context`.
But if you have multiple screens that contain `Chat` components where a client instance is necessary you will need to access the shared instance in other ways.

You can store the client in a [`context`](https://reactjs.org/docs/context.html) you create yourself.
Create your own custom class that provides it.
Or using the Singleton structure you can call `getInstance` when required to always be returned the current instance if one exists, or create a new one otherwise.

:::warning

Do not create and connect multiple instances using `new StreamChat()`, this will result in multiple `StreamChat` instances and opening multiple WebSocket connections.

:::

## Direct Interaction

There may be some direct interaction with the client that is required for your application.
Referring to the [full documentation](https://getstream.io/chat/docs/javascript/?language=javascript) is suggested for detailed information on client functionality.
Common interactions with the client used in conjunction with the Stream Chat for React Native components have been included for convenience.

### Creating a Channel

A channel must be initialized with either an `id` or a list of members for the channel.
If you provide a list of members an `id` will be auto-generated on backend for the channel.

:::note

You can't add or remove members from channel created using a list of members.

:::

<Tabs
  defaultValue='channelId'
  values={[
    { label: 'Channel Id', value: 'channelId' },
    { label: 'Members List', value: 'members' },
  ]}
>
<TabItem value='channelId'>

  ```ts
  /**
   *  Channel created using a channel id
   */
  const channel = client.channel(channel_type, 'channel_id', { 
      name: 'My New Channel', 
  });
  ```

</TabItem>
<TabItem value='members'>

  ```ts
  /**
   *  Channel created using a members list
   */
  const channel = client.channel(channel_type, {
      members: ['userOne', 'userTwo']
      name: 'My New Channel',
  });
  ```

</TabItem>
</Tabs>

To create a channel on the server you must call `create` or `watch` on a new channel instance.
`create` will create the channel while `watch` will both create the channel and subscribe the client to updates on the channel.

<Tabs
  defaultValue='watch'
  values={[
    { label: 'watch', value: 'watch' },
    { label: 'create', value: 'create' },
  ]}
>
<TabItem value='watch'>

  ```ts
  await channel.watch();
  ```

</TabItem>
<TabItem value='create'>

  ```ts
  await channel.create();
  ```

</TabItem>
</Tabs>

### Disconnecting a User

To disconnect a user you can call `disconnect` on the client.

```ts
await client.disconnectUser();
```
