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

ComponentsContext

ComponentsContext holds the override keys: for each replaceable part of the UI, the component the SDK renders there. Set keys with WithComponents, and read them with useComponentsContext(). Overriding components explains how overrides apply, and lists every key by area of the screen. This page covers the provider, the hook and their types.

Best practices

  • Declare the overrides object once, at module scope, with its components declared at module scope too. WithComponents reads it once, when it mounts.
  • Put WithComponents above the component that reads the key. OverlayProvider reads the image gallery's keys, MessageOverlayBackground and MessageActions, and Chat reads ChatLoadingIndicator, so those keys work only from a WithComponents around them. See Where to put WithComponents.
  • Read a key with useComponentsContext() in a component of your own, rather than importing the SDK's default, so it shows the override the app registered.
  • A custom message component receives no props. It reads the message with useMessageContext(). See A custom MessageItemView.

Basic usage

src/AppOverrides.tsx
import type { PropsWithChildren } from "react";
import { Text } from "react-native";
import { WithComponents } from "stream-chat-react-native";
import type {
  ComponentOverrides,
  EmptyStateProps,
} from "stream-chat-react-native";

const EmptyState = ({ listType }: EmptyStateProps) => (
  <Text>
    {listType === "channel" ? "No conversations yet" : "Nothing here yet"}
  </Text>
);

// Declared once, at module scope.
const overrides: ComponentOverrides = { EmptyStateIndicator: EmptyState };

export const AppOverrides = ({ children }: PropsWithChildren) => (
  <WithComponents overrides={overrides}>{children}</WithComponents>
);

A component of your own renders the same part through the context, so it shows EmptyState inside AppOverrides and the SDK's default elsewhere:

src/NoResults.tsx
import { useComponentsContext } from "stream-chat-react-native";

export const NoResults = () => {
  const { EmptyStateIndicator } = useComponentsContext();

  return <EmptyStateIndicator listType="default" />;
};

WithComponents

Prop Type Default Description
overrides ComponentOverrides required The keys to set for everything below. They replace the same keys from a WithComponents above, and the other keys keep their outer value. icons merges icon by icon. Read once, when it mounts.

WithComponents also renders its children. No provider removes the overrides from above; to give a part of the app the SDK's component back, set the key to the default component again.

useComponentsContext

useComponentsContext() returns a ResolvedComponents object: every key, with the overrides in effect merged over the SDK's defaults, and icons merged icon by icon. It never throws. Outside every WithComponents, it returns the defaults.

The object is built once for each component that calls the hook, when it mounts. An override registered later reaches the component only when it mounts again.

Types

Type What it is
ComponentOverrides The type of overrides. Every key is optional. It has 187 keys: 172 that have a default component, 14 optional slots that have none, and icons, a partial map of icon components.
ResolvedComponents The type useComponentsContext() returns. It types every key as defined, and icons as the full map.
Warning:

ResolvedComponents also types the 14 optional slots as defined, but they're undefined at runtime until you set them. Check one before rendering it, for example MessageText ? <MessageText {...props} /> : null.

The keys in the type that no component reads, and so change nothing, are listed in Keys that change nothing.

  • useComponentsContext() returns the merged keys, as above.
  • useMessageContext() gives a custom message component its message. See MessageContext.
  • useTheme() gives a custom component the theme, so it matches the SDK's. See Theming.