Info:
This is release candidate documentation for Stream Chat React Native SDK v10. For the latest stable version, see the latest version (v9).

Connection hooks

These hooks read the client's two connection stores: the WebSocket's health and the device's network. The two can disagree. A socket can drop on a working network, and a device can lose its network while the socket still looks healthy. Connection explains both stores, and Connection status shows them in the UI.

Each entry gives the signature, then:

  • Returns: what the hook gives back.
  • Reads: the store or the context it reads.
  • Re-renders: what makes the component render again.
  • Needs: where the component must sit, and what the hook does outside that place.

useWSConnectionState

Returns the health of the client's WebSocket.

useWSConnectionState(): WSConnectionState | undefined
  • Returns: { isHealthy, lastHealthyAt, lastUnhealthyAt }. isHealthy is always a boolean, so !isHealthy is safe. It's false before the first connection too, and only lastHealthyAt === null tells that apart from a drop.
  • Reads: client.wsConnection.state, all of it.
  • Re-renders: on every change to the store: each drop, each reconnect, and a deliberate client.closeConnection(), such as the one Chat makes when the app goes to the background.
  • Needs: Chat. Throws outside it.

The store records a drop the moment it happens, and most drops recover in under a second. For UI, use useSettledWSConnectionHealth, which waits before it reports a drop.

useWSConnectionStateSelector

Returns a selection of the WebSocket's health.

useWSConnectionStateSelector<O extends Readonly<Record<string, unknown> | Readonly<unknown[]>>>(
  selector: (state: WSConnectionState) => O,
): O | undefined
  • Returns: what the selector returns, an object or a tuple.
  • Reads: client.wsConnection.state, through your selector.
  • Re-renders: when a value in the selection changes. Define the selector at module scope: a new selector function on each render makes the hook subscribe again, as Selector identity explains.
  • Needs: Chat. Throws outside it.

useSettledWSConnectionHealth

Says whether the connection counts as healthy, ignoring short drops.

useSettledWSConnectionHealth(): boolean
  • Returns:

    • true as soon as the socket is up.
    • false once a drop has lasted client.wsConnection.config.offlineNotificationDisplayDelayMs, 5 seconds by default. A drop that ends sooner never reports false.
    • false at once when the socket is down while the device reports no network, or when the delay is 0.
    • Before the first connection has finished, true until the same delay has passed.

    A socket that has been up before and is down when the component mounts reads as false at once.

  • Reads: client.wsConnection.state (isHealthy and lastHealthyAt), client.networkConnection.state (isOnline) and client.wsConnection.configState (offlineNotificationDisplayDelayMs).

  • Re-renders: when the answer changes, and when one of those values changes.

  • Needs: Chat. Throws outside it.

The SDK's NetworkDownIndicator and ChannelListHeaderNetworkDownIndicator wait the same delay. To change it, set it in the client configuration:

client.config.set({
  client: { wsConnection: { offlineNotificationDisplayDelayMs: 2_000 } },
});

A banner of your own that says what is wrong reads both stores:

import { Text, View } from "react-native";
import type { NetworkConnectionState } from "stream-chat";
import {
  useNetworkConnectionStateSelector,
  useSettledWSConnectionHealth,
} from "stream-chat-react-native";

const isOnlineSelector = (state: NetworkConnectionState) => ({
  isOnline: state.isOnline,
});

export const ConnectionBanner = () => {
  const isHealthy = useSettledWSConnectionHealth();
  const { isOnline } =
    useNetworkConnectionStateSelector(isOnlineSelector) ?? {};

  if (isHealthy && isOnline !== false) return null;

  return (
    <View accessibilityLiveRegion="polite">
      <Text>
        {isOnline === false ? "Waiting for network..." : "Reconnecting..."}
      </Text>
    </View>
  );
};

useNetworkConnectionState

Returns the device's network status.

useNetworkConnectionState(): NetworkConnectionState | undefined
  • Returns: { isOnline, lastOnlineAt, lastOfflineAt }. isOnline is undefined while the status is unknown, so test isOnline === false. !isOnline is also true while the status is unknown.
  • Reads: client.networkConnection.state, all of it.
  • Re-renders: on every change to the store.
  • Needs: Chat. Throws outside it.

netInfoStatusReporter reports the status from @react-native-community/netinfo. useCreateChatClient installs it when it creates the client, and Chat when it mounts. See Device network.

useNetworkConnectionStateSelector

Returns a selection of the device's network status.

useNetworkConnectionStateSelector<O extends Readonly<Record<string, unknown> | Readonly<unknown[]>>>(
  selector: (state: NetworkConnectionState) => O,
): O | undefined
  • Returns: what the selector returns, an object or a tuple.
  • Reads: client.networkConnection.state, through your selector.
  • Re-renders: when a value in the selection changes. Define the selector at module scope, as ConnectionBanner above does.
  • Needs: Chat. Throws outside it.

Use it instead of useNetworkConnectionState when the component needs only part of the status.

useConnectionLifecycle

Closes the socket while the app is in the background, and installs the network status reporter.

useConnectionLifecycle(client: StreamChat, closeConnectionOnBackground?: boolean): void

It does three things:

  1. When the app goes to the background, it calls client.closeConnection(), unless closeConnectionOnBackground is false. It's true by default.
  2. When the app becomes active again, it calls client.openConnection(), if a user is connected. Unless closeConnectionOnBackground is false, it does the same when it mounts while the app is active and the socket was closed, which happens when Android recreates the activity.
  3. It sets netInfoStatusReporter as client.networkConnection.statusReporter in client.config, unless a reporter is registered there already.
  • Returns: nothing.
  • Reads: React Native's AppState. No store.
  • Re-renders: never by itself.
  • Needs: nothing. It takes the client as a param.

Chat calls it with its closeConnectionOnBackground prop. Call it yourself only in an app that uses the client without Chat. Under a Chat, a second call runs the same work twice, and a false passed to it doesn't stop the Chat from closing the socket. Closing the socket in the background explains why the socket closes.

Connection notifications

The SDK publishes no notification when the connection drops. NetworkDownIndicator at the top of each message list and ChannelListHeaderNetworkDownIndicator at the top of each channel list show the state instead. To show it elsewhere, use the hooks above, or publish a system notification yourself with useNotificationApi. Connection status lists what the SDK shows.