Chat UIKit React v3
Chat UIKit React
Chat UIKit
React
Version 3

Version migration guide

Copy link

UIKit v3 for React is now available. UIKit v3 has a dependency on Chat SDK v4. Before migrating from v2 to v3, refer to the migration guide of Chat SDK v4 for JavaScript for any breaking changes. The Chat SDK must be updated first before proceeding with the latest version of UIKit.

The biggest change from v2 to v3 is modularization, which allows you to build and customize views at a more minute level. You can execute key messaging functions, such as list channels, through modules. The smart components in v2 have now become modules that consist of separate providers and UI components. While the provider manages all the data of each module, the UI component renders user interfaces that are used to display the view of the module. The provider and UI components exchange data using context hooks. This new architecture allows for easier and more detailed customization.

When migrating from v2 to v3, there are several breaking changes you need to remember. While the properties of the smart components have relatively remained the same in the modules, some arguments in the render props have been removed. Refer to the breaking changes below.


Modules

Copy link

You can execute key chat functions through various modules provided by UIKit for React. In each module, there is a provider, a set of pre-built UI components, and a context hook that allows access to the provider's data. Refer to the table below to see which modules we provide and the components that make up each module.

ModuleProviderContext hookUI components

Channel list

ChannelListProvider

useChannelListContext

ChannelListUI

ChannelListHeader

ChannelPreview

Group channel

ChannelProvider

useChannelContext

ChannelUI

ChannelHeader

MessageInput

MessageList

Message

FileViewer

FrozenNotification

RemoveMessageModal

TypingIndicator

UnreadCount

Group channel settings

ChannelSettingsProvider

useChannelSettingsContext

ChannelSettingsUI

ModerationPanel

UserPanel

ChannelProfile

EditDetailsModal

exitChannel

UserListItem

Open channel

OpenChannelProvider

useOpenChannelContext

OpenChannelUI

OpenChannelHeader

OpenChannelInput

OpenChannelMessageList

OpenChannelMessage

FrozenChannelNotification

Open channel settings

OpenChannelSettingsProvider

useOpenChannelSettingsContext

OpenChannelSettingsUI

ModerationPanel

UserPanel

OpenChannelProfile

EditDetailsModal

Message search

MessageSearchProvider

useMessageSearchContext

MessageSearchUI

Create a channel

CreateChannelProvider

useCreateChannelContext

CreateChannelUI

InviteUsers

SelectChannelType

Edit user profile

EditUserProfileProvider

useEditUserProfileContext

EditUserProfileUI


Breaking changes

Copy link

See the breaking changes below for sendbirdSelectors and all modules.

Common changes

Copy link

The following table shows what common changes were made to the whole UIKit from v2 to v3.

From v2To v3

npm install sendbird-uikit

npm i @sendbird/uikit-react

sendbird-uikit/dist/index.css

@sendbird/uikit-react/dist/index.css

SendBirdProvider

SendbirdProvider

sendBirdSelectors

sendbirdSelectors

withSendBird()

withSendbird()

sendbirdSelectors

Copy link

The import path for sendbirdSelectors has changed after the name changed as shown in the code below.

import { sendBirdSelectors } from 'sendbird-uikit';
import sendbirdSelectors from '@sendbird/uikit-react/sendbirdSelectors';

Added UIKitMessageHandler

Copy link

A new interface called UIKitMessageHandler has been added in sendbirdSelectors for handling message events when sending a message. There are three options in the handler as shown in the code below.

const globalStore = useSendbirdStateContext();
const sendUserMessage = sendbirdSelectors.sendUserMessage(globalStore);

sendUserMessage(channel, { message: 'Hello world' })
    .onPending((message) => { })
    .onFailed((error, message) => { })
    .onSucceeded((message) => { })

Added new methods

Copy link

The following methods have been added for retrieving a channel instance.

Method nameDescription

getGetGroupChannel

Specifies a method that returns a Promise instance to retrieve a GroupChannel instance.

getGetOpenChannel

Specifies a method that returns a Promise instance to retrieve an OpenChannel instance.

const getGroupChannel = sendbirdSelectors.getGetGroupChannel(globalStore);
getGroupChannel('channel-url')
    .then((channel) => {})
    .catch((error) => {})

const getOpenChannel = sendbirdSelectors.getGetOpenChannel(globalStore);
getOpenChannel('channel-url')
    .then((channel) => {})
    .catch((error) => {})

getSendUserMessage

Copy link

The getSendUserMessage method and the getOpenChannelSendUserMessage method have combined into one getSendUserMessage. This method generates a function that returns UIKitMessageHandler to send user messages in group channels and open channels.

const sendUserMessage = sendBirdSelectors.getSendUserMessage(store);
const params = new sdk.UserMessageParams();
sendUserMessage('channel-url', params)
    .then((message) => {})
    .catch((error) => {})
const sendUserMessage = sendbirdSelectors.getSendUserMessage(globalStore);
sendUserMessage(channel, {} as UserMessageCreateParams)
    .onPending((message) => {})
    .onFailed((error, message) => {})
    .onSucceeded((message) => {})

getSendFileMessage

Copy link

The getSendFileMessage method and the getOpenChannelSendFileMessage method have combined into one getSendFileMessage. This method generates a function that returns UIKitMessageHandler to send file messages in group channels and open channels.

const sendFileMessage = sendBirdSelectors.getSendFileMessage(store);
const params = new sdk.FileMessageParams();
sendFileMessage('channel-url', params)
    .then((message) => {})
    .catch((error) => {})
const sendFileMessage = sendbirdSelectors.getSendFileMessage(globalStore);
sendFileMessage(channel, {} as FileMessageCreateParams)
    .onPending((message) => {})
    .onFailed((error, message) => {})
    .onSucceeded((message) => {})

getFreezeChannel parameter

Copy link

The parameter of getFreezeChannel changed from channel-url to GroupChannel or OpenChannel.

const freezeChannel = sendBirdSelectors.getFreezeChannel(store);
freezeChannel('channel-url')
    .then(() => {})
    .catch((error) => {})
const freezeChannel = sendbirdSelectors.getFreezeChannel();
freezeChannel(channel: GroupChannel | OpenChannel)
    .then(() => {})
    .catch(() => {})

getUnfreezeChannel parameter

Copy link

The parameter of getUnfreezeChannel changed from channel-url to GroupChannel or OpenChannel.

const unfreezeChannel = sendBirdSelectors.getUnfreezeChannel(store);
unfreezeChannel('channel-url')
    .then(() => {})
    .catch((error) => {})
const unfreezeChannel = sendbirdSelectors.getUnfreezeChannel();
unfreezeChannel(channel: GroupChannel | OpenChannel)
    .then(() => {})
    .catch(() => {})

getCreateGroupChannel

Copy link
From v2To v3

getCreateChannel

getCreateGroupChannel

When you call the getCreateGroupChannel method, it returns a Promise instance to create a new group channel.

const createChannel = sendBirdSelectors.getCreateChannel(store);
const params = new sdk.GroupChannelParams();
createChannel(params)
    .then((channel) => {})
    .catch((error) => {})
const createGroupChannel = sendbirdSelectors.getCreateGroupChannel(globalStore);
createGroupChannel({} as GroupChannelCreateParams)
    .then((channel) => {})
    .catch((error) => {})

How to create an open channel

Copy link

When you call the getCreateOpenChannel method, it returns a Promise instance to create a new open channel.

const createOpenChannel = sendBirdSelectors.getCreateOpenChannel(store);
const params = new sdk.OpenChannelParams();
createOpenChannel(params)
    .then((channel) => {})
    .catch((error) => {})
const createOpenChannel = sendbirdSelectors.getCreateOpenChannel(globalStore);
createOpenChannel({} as OpenChannelCreateParams)
    .then((channel) => {})
    .catch((error) => {})

getEnterOpenChannel

Copy link
From v2To v3

getEnterChannel

getEnterOpenChannel

When you call the getEnterOpenChannel method, it returns a Promise instance to enter an open channel.

const enterChannel = sendBirdSelectors.getEnterChannel(store);
enterChannel('channel-url')
    .then((channel) => {})
    .catch((error) => {})
const enterOpenChannel = sendbirdSelectors.getEnterOpenChannel(globalStore);
enterOpenChannel('channel-url')
    .then((channel) => {})
    .catch((error) => {})

getExitOpenChannel

Copy link
From v2To v3

getExitChannel

getExitOpenChannel

When you call the getExitOpenChannel method, it returns a Promise instance to exit an open channel.

const exitChannel = sendBirdSelectors.getExitChannel(store);
exitChannel('channel-url')
    .then((channel) => {})
    .catch((error) => {})
const exitOpenChannel = sendbirdSelectors.getExitOpenChannel(globalStore);
exitOpenChannel('channel-url')
    .then((channel) => {})
    .catch((error) => {})

getUpdateUserMessage

Copy link

The getUpdateUserMessage method and the getOpenChannelUpdateUserMessage method have combined into one getUpdateUserMessage. This method generates a function that returns a Promise instance to update user messages in group channels and open channels.

const updateUserMessage = sendBirdSelectors.getUpdateUserMessage(store);
const params = new sdk.UserMessageParams();
updateUserMessage('channel-url', 'message-id(number)', params)
    .then((message) => {})
    .catch((error) => {})
const updateUserMessage = sendbirdSelectors.getUpdateUserMessage(globalStore);
updateUserMessage(channel, 'message-id(number)', {} as UserMessageUpdateParams)
    .then((message) => {})
    .catch((error) => {})

getDeleteMessage

Copy link

The getDeleteMessage method and the getOpenChannelDeleteMessage method have combined into one getDeleteMessage. This method generates a function that returns a Promise instance to delete messages in group channels and open channels.

const deleteMessage = sendBirdSelectors.getDeleteMessage(store);
deleteMessage('channel-url', message)
    .then((message) => {})
    .catch((error) => {})
const deleteMessage = sendbirdSelectors.getDeleteMessage(globalStore);
deleteMessage(channel, message)
    .then((message) => {})
    .catch((error) => {})

getResendUserMessage

Copy link

The getResendUserMessage method and the getOpenChannelResendUserMessage method have combined into one getResendUserMessage. This method generates a function that returns a Promise instance to resend user messages in group channels and open channels.

const resendUserMessage = sendBirdSelectors.getResendUserMessage(store);
resendUserMessage('channel-url', failedMessage)
    .then((message) => {})
    .catch((error) => {})
const resendUserMessage = sendbirdSelectors.getResendUserMessage(globalStore);
resendUserMessage(channel, failedMessage)
    .then((message) => {})
    .catch((error) => {})

getResendFileMessage

Copy link

The getResendFileMessage method and the getOpenChannelResendFileMessage method have combined into one getResendFileMessage. This method generates a function that returns a Promise instance to resend file messages in group channels and open channels.

const resendFileMessage = sendBirdSelectors.getResendFileMessage(store);
resendFileMessage('channel-url', failedMessage)
    .then((message) => {})
    .catch((error) => {})
const resendFileMessage = sendbirdSelectors.getResendFileMessage(globalStore);
resendFileMessage(channel, failedMessage)
    .then((message) => {})
    .catch((error) => {})

ChannelList

Copy link

The ChannelList smart component has now become ChannelList module. See the codes below on how to import the new channel list module.

import { ChannelList } from 'sendbird-uikit';
import ChannelList from '@sendbird/uikit-react/ChannelList'
// Or use this code.
import { ChannelList } from '@sendbird/uikit-react'

Added new props

Copy link

The following table lists properties that were added to the ChannelList module.

Property nameTypeDescription

renderPlaceHolderError

ReactElement

Renders a customized placeholder for error messages in the channel list. (Default: null)

renderPlaceHolderLoading

ReactElement

Renders a customized placeholder for loading messages in the channel list. (Default: null)

renderPlaceHolderEmptyList

ReactElement

Renders a customized placeholder message for when the channel list is empty. (Default: null)

Channel

Copy link

The Channel smart component has now become Channel module. See the codes below on how to import the new group channel module.

import { Channel } from 'sendbird-uikit';
import Channel from '@sendbird/uikit-react/Channel'
// Or use this code.
import { Channel } from '@sendbird/uikit-react'

Renamed props

Copy link

The following table lists properties of the Channel module that were renamed.

From v2To v3

useReaction

isReactionEnabled

useMessageGrouping

isMessageGroupingEnabled

Removed render props

Copy link

The following render props have been removed from UIKit v3:

  • renderCustomMessage
  • renderChatItem

renderMessage

Copy link

See the code below on how to implement message-related actions in a group channel using the sendbirdSelectors component.

import { Channel, SendbirdProvider } from 'sendbird-uikit';

const MyCustomChatMessage = ({ message, onDeleteMessage, onUpdateMessage }) => (
    <div>
        {message.message}
        <button
            onClick={() => {
                const callback = () => { console.warn('message deleted'); }
                onDeleteMessage(message, callback);
            }}
        >
            Delete message.
        </button>
        <button
            onClick={() => {
                const updatedMessage = Math.random().toString();
                const callback = () => { console.warn('message updated'); }
                onUpdateMessage(message.messageId, updatedMessage, callback);
            }}
        >
            Update message.
        </button>
    </div>
);

const App = () => (
    <SendbirdProvider appId={appId} userId={userId}>
        <div style={{ height: '500px' }}>
            <Channel channelUrl={channelUrl} renderChatItem={MyCustomChatMessage} />
        </div>
    </SendbirdProvider>
);
<Channel
  renderMessage={MyFileMessageComponent}
/>
const MyFileMessageComponent = ({ message, chainTop, chainBottom }) => {
  const {
    currentGroupChannel,
    scrollToMessage,
  } = useChannelContext();
  const globalStore = useSendbirdStateContext();
  // Use sendbirdSelectors and globalStore to implement onDeleteMessage, onUpdateMessage, onResendMessage.
  const deleteFileMessage = sendbirdSelectors.getDeleteMessage(globalStore);
  if (message.messageType === 'file') {
    return (
      <div className="custom-file-message">
        <button
          className="custom-file-message__delete-button"
          onClick={deleteFileMessage(currentGroupChannel, message)}
        />
            Implement your code here.
      </div>
    )
  }
  return null;
}

Function signature

Copy link
Render propFrom v2To v3

renderMessageInput

({ channel, user, disabled, quoteMessage }) => React.ReactNode

() => React.ReactNode

renderChannelHeader

renderChatHeader?: ({ channel, user }) => React.ReactNode

renderChannelHeader?: () => React.ReactNode

How to render message input

Copy link

See the code below on how to render the MessageInput component with useChannel context hook and implement message-related actions in the channel using the sendbirdSelectors component.

<Channel
  renderMessageInput={MyMessageInput}
/>
const MyMessageInput = ({message, chainTop, chainBottom }) => {
  const {
    currentGroupChannel,
  } = useChannelContext();
  const globalStore = useSendbirdStateContext();
  // Use `sendbirdSelectors` and `globalStore` to implement `getSendUserMessage` and `getSendFileMessage`.
  const sendUserMessage = sendbirdSelectors.getSendUserMessage(globalStore);
  return (
    //...
  );
}

How to render header

Copy link

See the code below on how to render channel header with useChannel.

<Channel
  renderMessageInput={MyChannelHEader}
/>
const MyChannelHEader = () => {
  const {
    currentGroupChannel,
  } = useChannelContext();
  const globalStore = useSendbirdStateContext();
  const user = globalStore?.stores?.userStore?.user;
  return (
    //...
  );
}

Added new props

Copy link

The following table lists properties that were added to the Channel module.

Property nameTypeDescription

renderPlaceholderLoader

ReactElement

Renders a customized placeholder for loading messages in the channel. (Default: null)

renderPlaceholderInvalid

ReactElement

Renders a customized placeholder for invalid channel state. (Default: null)

renderPlaceholderEmpty

ReactElement

Renders a customized placeholder for an empty channel. (Default: null)

renderChannelHeader

ReactElement

Renders a customized channel header component. (Default: null)

renderMessage

ReactElement

Renders a customized message view in the channel. (Default: null)

renderMessageInput

ReactElement

Renders a customized message input component. (Default: null)

renderTypingIndicator

ReactElement

Renders a customized typing indicator component. (Default: null)

renderCustomSeparator

ReactElement

Renders a customized date separator view in the message list component. (Default: null)

ChannelSettings

Copy link

The ChannelSettings smart component has now become ChannelSettings module. See the codes below on how to import the new group channel settings module.

import { ChannelSettings } from 'sendbird-uikit';
import ChannelSettings from '@sendbird/uikit-react/ChannelSettings'
// Or use this code.
import { ChannelSettings } from '@sendbird/uikit-react'

Function signature

Copy link
Render propFrom v2To v3

renderChannelProfile

({ channel }) => React.ReactNode

() => React.ReactNode

How to render channel profile

Copy link

See the code below on how to render channel header with useChannelSettingsContext.

<ChannelSettings
  renderChannelProfile={MyChannelProfile}
/>
const MyChannelProfile = () => {
  const { channel } = useChannelSettingsContext();
  return (...);
}

Added new props

Copy link

The following table lists properties that were added to the ChannelSettings module.

Property nameTypeDescription

renderPlaceHolderError

ReactElement

Renders a customized placeholder for error messages that occur in the channel settings menu. (Default: null)

renderModerationPanel

ReactElement

Renders a customized view of the moderation panel that displays the moderation tools for channel operators. (Default: null)

renderExitChannel

ReactElement

Renders a customized leave channel button in the settings module. (Default: null)

OpenChannel

Copy link

The OpenChannel smart component has now become OpenChannel module. See the codes below on how to import the new open channel module.

import { OpenChannel } from 'sendbird-uikit';
import OpenChannel from '@sendbird/uikit-react/OpenChannel'
// Or use this code.
import { OpenChannel } from '@sendbird/uikit-react'

Function signature

Copy link
Render propFrom v2To v3

renderChannelTitle

({channel, user}) => React.ReactNode

() => React.ReactNode

renderMessageInput

({channel, user, disabled}) => React.ReactNode

() => React.ReactNode

Property names

Copy link
From v2To v3

renderCustomMessage

renderMessage

experimentalMessageLimit

messageLimit

useReaction

isReactionEnabled

useMessageGrouping

isMessageGroupingEnabled

How to render message, channel title, and message input

Copy link

See the code below on how to render the MessageInput component with useOpenChannelContext context hook and implement message-related actions in the channel using the sendbirdSelectors component.

<OpenChannel
  renderInput={MyMessage}
/>
const MyMessageInput = () => {
  // Use `useOpenChannelContext` to access current channel.
  const {
    currentOpenChannel,
  } = useOpenChannelContext();
  const globalStore = useSendbirdStateContext();
  // Use `sendbirdSelectors` and `globalStore` to implement `getSendUserMessage` and `getSendFileMessage`.
  const sendMessage = sendbirdSelectors.getSendUserMessage(globalStore);
  return (
    //...
  );
}

Added new props

Copy link

The following table lists properties that were added to the OpenChannel module.

Property nameTypeDescription

renderMessage

ReactElement

Renders a customized message view in the channel. (Default: null)

renderHeader

ReactElement

Renders a customized channel header component. (Default: null)

renderInput

ReactElement

Renders a customized message input component. (Default: null)

renderPlaceholderEmptyList

ReactElement

Renders a customized placeholder for an empty channel. (Default: null)

renderPlaceHolderError

ReactElement

Renders a customized placeholder for error messages that occur in the channel. (Default: null)

renderPlaceholderLoading

ReactElement

Renders a customized placeholder for loading messages in the channel. (Default: null)

OpenChannelSettings

Copy link

The OpenChannelSettings smart component has now become OpenChannelSettings module. See the codes below on how to import the new open channel settings module.

import { OpenChannelSettings } from 'sendbird-uikit';
import OpenChannelSettings from '@sendbird/uikit-react/OpenChannelSettings'
// Or use this code.
import { OpenChannelSettings } from '@sendbird/uikit-react'

Replaced renderChannelProfile

Copy link
From v2To v3

renderChannelProfile

renderOperatorUI, renderParticipantList

Added new props

Copy link

The following table lists properties that were added to the OpenChannelSettings module.

Property nameTypeDescription

renderOperatorUI

ReactElement

Renders a customized view of the channel settings for operators. (Default: null)

renderParticipantList

ReactElement

Renders a customized view of the channel settings for non-operator members. (Default: null)

MessageSearch

Copy link

The MessageSearch smart component has now become MessageSearch module. See the codes below on how to import the new message search module.

import { MessageSearch } from 'sendbird-uikit';
import MessageSearch from '@sendbird/uikit-react/MessageSearch'
// Or use this code.
import { MessageSearch } from '@sendbird/uikit-react'

Added new props

Copy link

The following table lists properties that were added to the MessageSearch module.

Property nameTypeDescription

renderPlaceHolderError

ReactElement

Renders a customized placeholder for error messages that occur in the search result. (Default: null)

renderPlaceholderLoading

ReactElement

Renders a customized placeholder for loading messages in the search result. (Default: null)

renderPlaceHolderNoString

ReactElement

Renders a customized placeholder for when there are no messages that match the search query.

renderPlaceholderEmptyList

ReactElement

Renders a customized placeholder for an empty list of search results. (Default: null)


Added new modules

Copy link

In v3, CreateChannel module and EditUserProfile module have been added. Go to the Create a channel page and Edit user profile page to learn more.