<Channel
...
DateHeader={undefined}
>
Overview
The core of Stream Chat for React Native is it’s ability to be customized to your needs. Many developers find that simply altering the theme is enough to achieve their desired results. But if more modification is needed, or functionality beyond what is provided out of the box is desired, creating a custom component is likely the best course of action.
When to use a custom component
Understanding what is customizable is helpful in determining when to build a custom component. If you want to insert your one or more components into another component, you need to create a custom component. If you want to change the layout of a component significantly, you need to create a custom component. If you want to change the internal functionality of a component, you need to create a custom component. A good way to think about it is, with few exceptions, what you see is what you get. The library can’t account for every possible use case out of the box, but don’t worry building and using custom components is easy.
Exceptions
- Padding, fonts, colors, borders, etc. can all be altered from the theme as styles are passed to most components and sub-components.
- Messages can be aligned to one side using the
forceAlignMessages
prop on theChannel
component. - Message content can be reordered using the
messageContentOrder
prop onChannel
; but you may want to adjust the theming to account for changes to border alignments if you alter this order.
Changes to content beyond these tweaks will require custom components.
If your goal is simply to remove a UI feature you can always replace the component with one that returns null
to achieve this, that is () => null
.
How to use a custom component
Most custom components are provided to the UI as props on the Channel
component.
The OverlayProvider
, MessageList
, and ChannelList
have a few exceptions to this rule, but Channel
is the primary entry point.
Let’s say you want to remove the fixed DateHeader
on the message list. You can pass the value undefined
into it.
The new custom component takes the place of the default DateHeader
within a context and is then provided to and rendered wherever the default DateHeader
currently is.
The component can be just as easily swapped out for one that renders something different than the original instead of null
.
Most components rely on context for receiving data, but some use props instead or as well.
In the case of DateHeader
the component will be rendered with the prop dateString
which is a string
.
const MyNewComponent = ({ dateString }) => <Text>{`Hello World: ${dateString}`}</Text>;
<Channel
...
DateHeader={MyNewComponent}
>
Using contexts
At the core of creating custom components is the ability to access pertinent data from the contexts Stream Chat for React Native provides.
The hooks provided allow you to access this contextual information easily throughout your application.
Keep in mind when developing that these hooks are only usable within the scope of their context providers.
Certain contexts, such at MessageContext
, are only available within the scope of a single Message
so you cannot use this hook in for instance the DateHeader
.
To demonstrate this usage the DateHeader
can be replaced with a component that makes use of context.
Messages can be pulled from the PaginatedMessageListContext
and the name of the last sender from the list can be retrieved and displayed in place of the DateHeader
.
const MySenderComponent = () => {
const { messages } = usePaginatedMessageListContext();
const latestMessageSender = messages[messages.length - 1]?.user?.name;
return <Text>{`Last Sender: ${latestMessageSender}`}</Text>;
};
<Channel
...
DateHeader={MySenderComponent}
>
This allows you as a developer to not only customize the look and feel of every part of the UI, but also decide what information is shown where based on your own design.
Custom components within a Message
should draw from mostly static contexts with the exception of their own MessageContext
.
ThemeContext
, MessagesContext
, and TranslationContext
all remain static with few exceptions and can be used.
This should be done as memoization of a value from a context surrounding the FlatList
from a component within the FlatList
does not work properly when the context updates.
Pulling directly from the PaginatedMessageListContext
within a Message
for instance would cause every Message
to re-render to some degree when the message list updates.