# Channel and channel state

> **Info:** This is release candidate documentation for **Stream Chat React SDK v15**. For the latest stable version, see the [latest version (v14)](https://getstream.io/chat/docs/sdk/react/).

A `Channel` is the client's object for one channel. Its data, members, read state and typing users are in the store `channel.state`. Its messages, pinned messages, composer and message operations are objects it owns. This page lists the API of `Channel` and `ChannelState` in `stream-chat`.

What a channel holds, and why, is explained on [What channels and threads hold](https://getstream.io/chat/docs/sdk/react/v15/state/channels-and-threads/what-channels-and-threads-hold/). Getting and loading a channel is explained on [Shared entities](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/shared-entities/).

## Getting a channel

The client keeps one `Channel` per cid. Get it from the client instead of constructing it with `new Channel()`:

| Call                               | Returns                                                                                                                                                                                                                      |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client.channel(type, id, custom)` | The stored channel for `type:id`, or a new one that the client stores from then on. Sends no request. `id` and `custom` are optional. `client.channel(type, { members })` creates a channel from its members, without an id. |
| `client.channelManager.get(cid)`   | The stored channel, or `undefined`. A stored channel can be one that was disposed.                                                                                                                                           |
| `Channel.watch(options)`           | Watches and loads the channel unless that's done already, and resolves with the instance to use from then on. `options` is optional.                                                                                         |

A few rules apply to `client.channel()`:

- It throws without a user. Call it after `client.connectUser()`, which doesn't have to finish first.
- For a channel the client already stores, it applies only the `custom` field of its last argument and ignores the rest.
- A stored channel that was disposed is replaced by a new instance.
- Without an `id`, `members` creates a distinct channel between those members. It's provisional until its first query answers. A channel with neither isn't stored.

This opens "general" and watches it, whether or not another part of the app is opening it at the same time:

```ts
const general = await client.channel("messaging", "general").watch();
```

A channel identifies itself with these properties:

| Property        | What it holds                                                                                                 |
| --------------- | ------------------------------------------------------------------------------------------------------------- |
| `cid`           | `type:id`. A channel created from its members has a temporary cid until the server assigns its id.            |
| `id`            | The channel id, or `undefined` while the channel is provisional.                                              |
| `type`          | The channel type, such as `messaging`.                                                                        |
| `isProvisional` | `true` while the channel has no id. Not in a store: subscribe to `initialized`, which the same response sets. |

## The objects a channel owns

| Property                          | What it is                                                                                                                                                     |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `channel.state`                   | The `ChannelState` store described below.                                                                                                                      |
| `channel.messagePaginator`        | The channel's message list. See [Message paginator](https://getstream.io/chat/docs/sdk/react/v15/reference/state/message-paginator/).                                              |
| `channel.pinnedMessagesPaginator` | The channel's pinned messages. See [Pinned messages paginator](https://getstream.io/chat/docs/sdk/react/v15/reference/state/pinned-messages-paginator/).                           |
| `channel.messageComposer`         | The composer for new messages. See [MessageComposer API](https://getstream.io/chat/docs/sdk/react/v15/reference/state/messagecomposer-api/).                                       |
| `channel.messageOperations`       | Sends, retries, edits and deletes messages, and adds reactions. See [Message operations](https://getstream.io/chat/docs/sdk/react/v15/state/writing-messages/message-operations/). |
| `channel.messageReceiptsTracker`  | Who read and who received each message. See [Message receipts tracker](https://getstream.io/chat/docs/sdk/react/v15/reference/state/message-receipts-tracker/).                    |
| `channel.cooldownTimer`           | The slow mode countdown for the current user. See [Slow mode](https://getstream.io/chat/docs/sdk/react/v15/state/channels-and-threads/what-channels-and-threads-hold/#slow-mode).  |

A thread has its own message list, composer and message operations. Inside a thread, use the thread's, not the channel's.

## channel.state fields

`channel.state` is a `ChannelState`, a store of `ChannelStateData`. Every field below is in that one store, so a subscription selects the fields it needs:

| Field             | Type                                      | What it holds                                                                                                                                                                                                      |
| ----------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `data`            | `Partial<ChannelResponse>` or `undefined` | The channel's server data: `name`, `image`, `frozen`, `hidden`, `cooldown`, `member_count`, `own_capabilities`, `custom` and the rest. Before the first load, the data passed to `client.channelManager.ensure()`. |
| `members`         | `Record<string, ChannelMemberResponse>`   | The loaded members, by user id. A large channel loads only some of them.                                                                                                                                           |
| `memberCount`     | `number`                                  | The total member count, from `data.member_count`.                                                                                                                                                                  |
| `membership`      | `ChannelMemberResponse`                   | The current user's own membership: `channel_role`, `archived_at`, `pinned_at` and the rest. An empty object until it's loaded.                                                                                     |
| `watchers`        | `Record<string, UserResponse>`            | The users watching the channel now, by user id.                                                                                                                                                                    |
| `watcherCount`    | `number`                                  | How many users are watching.                                                                                                                                                                                       |
| `watchStatus`     | `ChannelWatchStatus`                      | Whether this client watches the channel: `"watching"`, `"wasWatching"` (the connection dropped) or `"notWatching"`.                                                                                                |
| `read`            | `Record<string, ...>`                     | Each member's read state, by user id. The fields are in the next table.                                                                                                                                            |
| `typing`          | `Record<string, Event>`                   | Who is typing, by user id: each user's latest `typing.start` event.                                                                                                                                                |
| `ownCapabilities` | `string[]`                                | What the current user may do here, such as `send-message` or `upload-file`.                                                                                                                                        |
| `muteStatus`      | `ChannelMuteStatus`                       | `{ muted, createdAt, expiresAt }`. The dates are in nanoseconds, or `null`.                                                                                                                                        |
| `initialized`     | `boolean`                                 | A live server response was applied to this instance. Data from the offline database doesn't count.                                                                                                                 |
| `offlineMode`     | `boolean`                                 | The data came from the offline database, not from the server.                                                                                                                                                      |
| `active`          | `boolean`                                 | Something has activated the channel with `Channel.activate()` and not released it yet.                                                                                                                             |
| `pendingDisposal` | `boolean`                                 | The instance was disposed and can't be used any more.                                                                                                                                                              |
| `supersededBy`    | `Channel` or `undefined`                  | The instance that replaced this one. See [Superseded channels](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/entity-lifecycle/#superseded-channels).                                                           |
| `aiState`         | `AIState`                                 | The state of an AI response: one of the `AIStates` values, `AIStates.Idle` by default.                                                                                                                             |

Each entry of `read` has these fields. The timestamps are in nanoseconds:

| Field                       | What it holds                                                 |
| --------------------------- | ------------------------------------------------------------- |
| `user`                      | The user.                                                     |
| `last_read`                 | When the user last read the channel.                          |
| `unread_messages`           | How many messages the user hasn't read.                       |
| `last_read_message_id`      | The last message the user read, when the server knows it.     |
| `first_unread_message_id`   | The message the user marked unread from, after a mark unread. |
| `last_delivered_at`         | When a message was last delivered to the user.                |
| `last_delivered_message_id` | The last message delivered to the user.                       |

[Read state and unread counts](https://getstream.io/chat/docs/sdk/react/v15/state/channels-and-threads/read-state-and-unread-counts/) explains which events change it.

This handler runs whenever the member count or the current user's unread count changes:

```ts
const ownUserId = client.userId;

const unsubscribe = channel.state.subscribeWithSelector(
  ({ memberCount, read }) => ({
    memberCount,
    unread: ownUserId ? (read[ownUserId]?.unread_messages ?? 0) : 0,
  }),
  ({ memberCount, unread }) => {
    console.log(`${memberCount} members, ${unread} unread`);
  },
);
```

### Getters

These getters return the value at the moment you read them, and don't tell you when it changes. To follow a change, subscribe to `channel.state`.

| Getter                                                      | What it reads                                          |
| ----------------------------------------------------------- | ------------------------------------------------------ |
| `channel.data`                                              | `data`                                                 |
| `channel.initialized`, `channel.offlineMode`                | `initialized`, `offlineMode`                           |
| `channel.watchStatus`, `channel.active`                     | `watchStatus`, `active`                                |
| `channel.pendingDisposal`, `channel.supersededBy`           | `pendingDisposal`, `supersededBy`                      |
| `channel.state.members`, `channel.state.membership`         | `members`, `membership`                                |
| `channel.state.read`, `channel.state.watchers`              | `read`, `watchers`                                     |
| `channel.state.member_count`, `channel.state.watcher_count` | `memberCount`, `watcherCount`                          |
| `channel.state.typing`                                      | The typing users, as the channel's composer holds them |
| `channel.state.unreadCount`                                 | The current user's `unread_messages`, or `0`           |

`channel.state.pending_messages` holds the channel's pending messages from the last query. It isn't in the store.

Some of these have setters. They exist for the SDK: app code changes a channel through the methods below, not by writing its state.

## Configuration

A channel has two views of its settings:

- **`channel.config`** is the configuration in effect: the channel type's server settings combined with what the app registered in `client.config`. `channel.configState` is the same value as a store.
- **`channel.serverConfig`** is the channel type's settings as the server sent them (`ChannelConfigWithInfo`): `typing_events`, `read_events`, `replies`, `uploads`, `url_enrichment`, `polls`, `max_message_length`, `commands` and the rest. It's `undefined` until the channel has been queried or watched.

Check `channel.config` to decide whether a feature is available. Either side can turn a feature off, and only `config` includes both. `channel.config` has these fields:

| Field                                | Default | Combined with the server's                                                    |
| ------------------------------------ | ------- | ----------------------------------------------------------------------------- |
| `typingEvents.enabled`               | `true`  | `typing_events`                                                               |
| `readEvents.enabled`                 | `true`  | `read_events`                                                                 |
| `readEvents.localUnreadCountEnabled` | `false` | Nothing. Counts unread messages locally while read events are off.            |
| `replies.enabled`                    | `true`  | `replies`                                                                     |
| `userMessageReminders.enabled`       | `true`  | `user_message_reminders`                                                      |
| `deliveryEvents.enabled`             | `true`  | `delivery_events`                                                             |
| `availableCommands`                  | `[]`    | `commands`, which it copies. The app can't set it.                            |
| `requestHandlers`                    | none    | Nothing. Replaces the requests for send, retry, update, delete and mark read. |

Change these through `client.config`, under the `channel` key. A channel has no `updateConfig()`:

```ts
client.config.set({
  channel: {
    readEvents: { enabled: false, localUnreadCountEnabled: true },
    typingEvents: { enabled: false },
  },
});
```

The `channel` key also holds `messagePaginator`, `pinnedMessagesPaginator` and `messageOperations`, which go to the objects the channel owns. [Configuration](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/configuration/) explains how settings resolve, and [Configuration tree](https://getstream.io/chat/docs/sdk/react/v15/reference/state/configuration-tree/) lists every key.

## Loading and lifecycle methods

| Method                                  | Returns                         | What it does                                                                                                                                                                                                                                                                                                                                      |
| --------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `watch(options, requestOptions)`        | `Promise<Channel>`              | Loads the channel, its members, read state and latest messages, and watches it. Safe to call again, even from several places at once: it sends a request only when the channel isn't loaded yet, or when `options` differ from those it was watched with. Resolves with this instance or the one that superseded it. Both arguments are optional. |
| `query(options)`                        | `Promise<ChannelStateResponse>` | Loads the channel with the options you pass. Watches it only with `watch: true`. The messages it returns aren't added to the message list.                                                                                                                                                                                                        |
| `create(options)`                       | `Promise<ChannelStateResponse>` | Creates the channel on the server, or gets it, without watching it. Asks for no messages, members or read state.                                                                                                                                                                                                                                  |
| `reload()`                              | `Promise<void>`                 | Watches again and refreshes the newest loaded messages, keeping messages that failed to send. Use it to refresh a watched channel: repeating `watch()` doesn't. Does nothing for a channel that was never loaded.                                                                                                                                 |
| `stopWatching(request, requestOptions)` | `Promise<Response>`             | Ends the watch. `watchStatus` becomes `"notWatching"`, and a reconnect doesn't restore it.                                                                                                                                                                                                                                                        |
| `activate()`                            | `() => void`                    | Marks the channel active and returns the function that releases it. Activations are counted.                                                                                                                                                                                                                                                      |
| `disconnect()`                          | `void`                          | Disposes the instance: `pendingDisposal` becomes `true`. Sends no request, so call `stopWatching()` first to end the watch.                                                                                                                                                                                                                       |
| `getClient()`                           | `StreamChat`                    | The client. Throws once the channel is disposed.                                                                                                                                                                                                                                                                                                  |

`options` for `Channel.watch()`, `Channel.query()` and `Channel.create()` is a `ChannelGetOrCreateRequest`: `messages`, `members` and `watchers` pagination, `presence`, `state`, `watch`, `data` and a few more. `Channel.watch()` and any query with `watch: true` wait for the WebSocket to connect. [Shared entities](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/shared-entities/#loading) explains loading, and [Entity lifecycle](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/entity-lifecycle/) explains activation and disposal.

This keeps a channel loaded while a screen shows it:

```ts
const openScreen = async (id: string) => {
  const opened = await client.channel("messaging", id).watch();
  // Until release() is called, reconnects reload the channel.
  const release = opened.activate();
  return { channel: opened, close: release };
};
```

## Channel actions

Most methods below send a request. Unless the table says otherwise, the change shows when the server's event arrives, not when the call returns. Most of them take an optional `requestOptions` as their last argument, which carries an abort `signal`. `Channel.banUser()`, `Channel.unbanUser()`, `Channel.markReadViaReporter()` and `Channel.sendSharedLocation()` don't. [What's optimistic and what isn't](https://getstream.io/chat/docs/sdk/react/v15/state/writing-messages/whats-optimistic-and-what-isnt/) lists how each action settles.

### The current user's membership

| Method                              | What it does                                                                                                                                                     |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `archive()`, `unarchive()`          | Sets or clears `membership.archived_at`, on `member.updated`.                                                                                                    |
| `pin()`, `unpin()`                  | Sets or clears `membership.pinned_at`, on `member.updated`.                                                                                                      |
| `mute({ expiration })`              | Mutes the channel, for `expiration` milliseconds if given. `muteStatus` changes on `notification.channel_mutes_updated`.                                         |
| `unmute()`                          | Unmutes the channel, on the same event.                                                                                                                          |
| `muteStatus()`                      | Returns the current `ChannelMuteStatus`, without a request. Throws for a provisional channel.                                                                    |
| `hide({ clear_history })`, `show()` | Hides the channel from the user's channel lists until a new message arrives, or shows it again. `data.hidden` changes on `channel.hidden` and `channel.visible`. |

### Members

| Method                                                   | What it does                                                                                       |
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `addMembers({ members, ...options })`                    | Adds members by user id or as `ChannelMemberRequest` objects. `members` changes on `member.added`. |
| `removeMembers({ members, ...options })`                 | Removes members. `members` changes on `member.removed`.                                            |
| `inviteMembers({ members, ...options })`                 | Invites users.                                                                                     |
| `acceptInvite(options)`, `rejectInvite(options)`         | Accepts or rejects the current user's invitation.                                                  |
| `banUser(userId, options)`, `unbanUser(userId, options)` | Bans or unbans a user in this channel.                                                             |
| `queryMembers({ payload })`                              | A one-off query of members. Changes no state.                                                      |

`message` and `options` are optional, except that `Channel.banUser()` needs `options`, even if it's `{}`. `message` is a system message to send with the change.

### Channel data

| Method                                                  | What it does                                                                                                                        |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `update(request)`                                       | Replaces the channel's data, for example `{ data: { name } }`. Applies the response to `data` at once.                              |
| `updatePartial({ set, unset })`                         | Changes some fields. Applies the response to `data` at once, and dispatches `capabilities.changed` when `own_capabilities` changed. |
| `enableSlowMode(seconds)`, `disableSlowMode()`          | Sets `data.cooldown`, through `update()`.                                                                                           |
| `addFilterTags({ tags })`, `removeFilterTags({ tags })` | Changes the channel's filter tags, through `update()`.                                                                              |
| `truncate(request)`                                     | Removes the channel's messages, or those before `truncated_at`. The lists change on `channel.truncated`.                            |
| `delete({ hard_delete })`                               | Deletes the channel. On `channel.deleted`, the client disposes the instance.                                                        |

### Read state

| Method                         | What it does                                                                                                                                                                                                    |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `markRead(request)`            | Sends the mark read request directly. Throws before the channel is loaded, or when `config.readEvents.enabled` is `false`. `read` changes on `message.read`.                                                    |
| `markReadViaReporter(request)` | Marks the channel read through `client.messageDeliveryReporter`. Uses `requestHandlers.markReadRequest` when registered, and `markReadLocally()` while read events are off and `localUnreadCountEnabled` is on. |
| `markReadLocally()`            | Resets the current user's unread count without a request, by dispatching `message.read_locally`. Returns the event, or `undefined` without a user.                                                              |
| `markUnread(request)`          | Marks the channel unread from `request.message_id` or `request.message_timestamp`. Throws like `markRead()`. `read` changes on `notification.mark_unread`.                                                      |
| `countUnread(lastRead)`        | Counts the newest loaded messages after `lastRead` that count as unread. Without `lastRead`, returns `state.unreadCount`.                                                                                       |
| `countUnreadMentions()`        | Counts the newest loaded unread messages that mention the current user.                                                                                                                                         |
| `lastRead()`                   | The current user's `last_read`, `null` if never read, or `undefined` without a user.                                                                                                                            |

### Typing, events and AI

| Method                                     | What it does                                                                                                                    |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `keystroke(parentId)`                      | Sends `typing.start`, at most every 2 seconds. Pass a parent message id for a thread. Does nothing while typing events are off. |
| `stopTyping(parentId)`                     | Sends `typing.stop`.                                                                                                            |
| `sendEvent({ event })`                     | Sends a custom event to the channel.                                                                                            |
| `updateAIState(messageId, state, options)` | Sends `ai_indicator.update` for a message. Usually called by the server that runs the AI.                                       |
| `clearAIIndicator()`, `stopAIResponse()`   | Send `ai_indicator.clear` and `ai_indicator.stop`.                                                                              |

### Requests that change no state

These send the request and return the response. Nothing in the channel's state changes until an event arrives:

- `Channel.sendMessage(request)`, `Channel.sendReaction(...)` and `Channel.deleteReaction(...)`. Use [`channel.messageOperations`](https://getstream.io/chat/docs/sdk/react/v15/state/writing-messages/message-operations/), which also updates the message list.
- `Channel.getPinnedMessages(request)`, `Channel.getMessagesById(ids)`, `Channel.queryChannelBans(request)` and `Channel.getDraft(request)`.
- `Channel.uploadFile(request)`, `Channel.uploadImage(request)`, `Channel.deleteFile({ url })` and `Channel.deleteImage({ url })`.
- `Channel.vote(...)` and `Channel.removeVote(...)` for polls, and `Channel.sendSharedLocation(location)` and `Channel.stopLiveLocationSharing(location)` for locations.

## Events

`Channel.on(type, handler)` and `Channel.on(handler)` subscribe to the channel's events, and return `{ unsubscribe }`. `Channel.off(type, handler)` removes a handler. The client applies an event to the channel's state before any handler runs, so a handler reads the updated state. A disposed channel's state no longer changes, but its handlers still run.

```ts
const { unsubscribe } = channel.on("member.added", (event) => {
  // channel.state already holds the new member
  console.log(`${event.member?.user?.name} joined`, channel.state.members);
});
```

The channel changes its state on these events:

| Event                                                                              | What changes                                                                                                                                                                                                                                                                                                                          |
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message.new`                                                                      | The message list and the pinned list. Each `unread_messages` in `read` grows, except the sender's, which is reset to 0. The current user's grows only for a message that counts as unread, and the current user's own message changes no count. A hidden channel becomes visible. A thread-only reply changes neither list nor count. |
| `message.updated`, `message.undeleted`, `message.deleted`, `user.messages.deleted` | The message list and the pinned list. `message.updated` and `message.undeleted` skip replies.                                                                                                                                                                                                                                         |
| `reaction.new`, `reaction.updated`, `reaction.deleted`                             | The message, in every list that shows it.                                                                                                                                                                                                                                                                                             |
| `message.read`, `notification.mark_read`, `message.read_locally`                   | The reader's entry in `read`. A thread read changes nothing here.                                                                                                                                                                                                                                                                     |
| `notification.mark_unread`                                                         | The current user's entry in `read`, and the message list's unread snapshot.                                                                                                                                                                                                                                                           |
| `message.delivered`                                                                | The delivery fields of the user's entry in `read`.                                                                                                                                                                                                                                                                                    |
| `typing.start`, `typing.stop`                                                      | `typing`. An entry older than 7 seconds is removed, and the client dispatches `typing.stop` for it.                                                                                                                                                                                                                                   |
| `member.added`, `member.updated`                                                   | `members`, and `membership` for the current user.                                                                                                                                                                                                                                                                                     |
| `member.removed`                                                                   | `members`.                                                                                                                                                                                                                                                                                                                            |
| `user.banned`, `user.unbanned`                                                     | The member's `banned` and `shadow_banned`.                                                                                                                                                                                                                                                                                            |
| `user.watching.start`, `user.watching.stop`                                        | `watchers`.                                                                                                                                                                                                                                                                                                                           |
| `channel.updated`                                                                  | `data`, `memberCount` and `ownCapabilities`. When `frozen` changes, the channel queries itself again to refresh `ownCapabilities`.                                                                                                                                                                                                    |
| `channel.truncated`                                                                | `data`, the message list, the pinned list and the current user's unread count.                                                                                                                                                                                                                                                        |
| `channel.hidden`, `channel.visible`                                                | `data.hidden`. With `clear_history`, `channel.hidden` also empties the message list and the pinned list.                                                                                                                                                                                                                              |
| `ai_indicator.update`, `ai_indicator.clear`, `ai_indicator.stop`                   | `aiState`.                                                                                                                                                                                                                                                                                                                            |
| Any event with `watcher_count`                                                     | `watcherCount`.                                                                                                                                                                                                                                                                                                                       |

These are handled by the client, for every channel it stores:

| Event                                                                                    | What changes                                                                                   |
| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `notification.channel_mutes_updated`, `health.check`, `connection.ok`                    | `muteStatus`.                                                                                  |
| `notification.mark_read` with `unread_channels: 0`                                       | The current user's unread count, in every channel.                                             |
| `user.updated`, `user.presence.changed`                                                  | The user's object in `members`, `membership` and `watchers`, and in `read` for `user.updated`. |
| `user.deleted` that deletes the user's messages, `user.messages.deleted` without a `cid` | That user's messages in the message list and the pinned list.                                  |
| `channel.deleted`, `notification.channel_deleted`, `notification.removed_from_channel`   | The channel is disposed: `pendingDisposal` becomes `true`.                                     |

The client also dispatches events of its own. `capabilities.changed` fires when a query or `Channel.updatePartial()` returns different capabilities, and `channels.queried` fires after every query.

>
> **Note:** `user.watching.start`, `user.watching.stop`, `user.banned` and `user.unbanned` change `watchers` and `members` in place, without a new object. So does a query that loads watchers. A subscription that selects `watchers` or `members` misses the change until another update replaces the object. `member.removed` doesn't clear `membership` when the current user is removed.
>

## See also

- [What channels and threads hold](https://getstream.io/chat/docs/sdk/react/v15/state/channels-and-threads/what-channels-and-threads-hold/) explains the channel's state.
- [Shared entities](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/shared-entities/) and [Entity lifecycle](https://getstream.io/chat/docs/sdk/react/v15/state/state-and-entities/entity-lifecycle/) explain getting, loading and releasing channels.
- [Thread and thread manager](https://getstream.io/chat/docs/sdk/react/v15/reference/state/thread-and-thread-manager/) lists the API of threads.

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v15/reference/state/channel-and-channel-state/](https://getstream.io/chat/docs/sdk/react/v15/reference/state/channel-and-channel-state/).