Home
/
UIKit
/
React

Common components

You can implement UIKit for React by using the following components. These components support both open channels and group channels.


SendBirdProvider

SendBirdProvider is the context provider that passes the Chat SDK down to the child components, and is the most important component in UIKit for React. The React Context API is used to easily pass down data through components. By using withSendBird() HOC or useSendbirdStateContext(), Sendbird Chat SDK for Javascript can be implemented in any component under the SendBirdProvider which has the following properties:

List of properties

RequiredTypeDescription

appId

string

The APP_ID of the Sendbird application.

userId

string

The unique ID of the user.

OptionalTypeDescription

accessToken

string

The opaque string that identifies the user. It is recommended that every user has their own access token and provides it upon login for security. (Default: null)

theme

string

A style applied to the app. Available themes are light and dark. (Default: light)

nickname

string

The user’s nickname. (Default: null)

profileUrl

string

The URL of the user’s profile image. (Default: null)

userListQuery

interface

The query factory class to retrieve a list of filtered users and manually added users. (Default: Chat SDK's ApplicationUserListQuery)

stringSet

object

The set of strings for UIKit components. This can override the default language. (Default: null)

colorSet

object

The set of colors used in the UIKit themes. This can overrides the default theme. (Default: null)

Note : The App component internally manages the SendBirdProvider as well as other components and can be used to configure the above properties.


withSendBird()

The withSendBird() is an HOC that helps you access data in the Chat SDK, and internally supports the Channel, ChannelList and ChannelSettings. Using the withSendBird(), data stored in the SendBirdProvider state, which is stored through the React Context API, can be accessed. The withSendBird() can be used to not only implement chat features, but also to access stored data for further customization.

Note : The Chat SDK can be accessed at state.stores.sdkStore.sdk or using sendBirdSelectors.getSdk()

Light Color Skin
Copy
const CustomReactComponentWithSendBirdConsumer = withSendBird(CustomReactComponent, mapStateToProps);

sendBirdSelectors

sendBirdSelectors provides many useful selectors to perform various data operations and can also be used to write customized selectors. The main functionalities of sendBirdSelectors regarding the Chat SDK are listed below.

List of functions

FunctionDescription

getConnect

Connects a user to Sendbird server.
Signature: (store) => (userId, accessToken) => Promise<(User, error)>

getDisconnect

Disconnects a user from Sendbird server.
Signature: (store) => (userId, accessToken) => Promise<(_, error)>

getUpdateUserInfo

Updates a user’s information such as nickname or profile image.
Signature: (store) => (userId, accessToken) => Promise<(User, error)>

getSdk

Returns the SDK instance of a user.
Signature:
(store) => sdk

getCreateChannel

Creates a new channel with params.
Signature: (store) => (GroupChannelParams) => Promise<(GroupChannel, error)>

getLeaveChannel

Leaves a channel.
Signature: (store) => (channelUrl) => Promise<(_, error)>

getSendUserMessage

Returns a promise chain which sends a user message to a specific channel.
Signature: (store) => (channelUrl, UserMessageParams) => Promise<(PendingMessage, error)> => Promise<(UserMessage, error)>

getSendFileMessage

Returns a promise chain to send a file message to a specific channel.
Signature: (store) => (channelUrl, FileMessageParams) => Promise<(PendingMessage, error)> => Promise<(FileMessage, error)>

getUpdateUserMessage

Updates a user message.
Signature: (store) => (channelUrl, messageId, UserMessageParams) => Promise<(UserMessage, error)>

getDeleteMessage

Deletes a user message.
Signature: (store) => (channelUrl, message) => Promise<(_, error)>

getResendUserMessage

Resends a failed user message.
Signature: (store) => (channelUrl, FailedUserMessage) => Promise<(Message, error)>

getResendFileMessage

Resends a failed file message.
Signature: (store) => (channelUrl, FailedFileMessage) => Promise<(FileMessage, error)>

The sample code below shows how to implement sendBirdSelectors with its properties.

getDisconnect
getSDK
getCreateChannel&more
getSendUserMessage&more
Light Color Skin
Copy
import {
    SendBirdProvider,
    withSendBird,
    sendBirdSelectors,
} from "sendbird-uikit";
import "sendbird-uikit/dist/index.css";

const MyButton = (props) => {
    <button onClick={() => props.disconnect().then((reject, response) => { ... }); }>
        > Disconnect
    </button>
}

const ButtonWithSendBird = withSendBird(MyButton, (state) => {
    disconnect: sendBirdSelectors.getDisconnect(state),
});

const App = () => {
    <SendBirdProvider appId={appId} userId={userId}>
        <div>
            <ButtonWithSendBird />
        </div>
    </SendBirdProvider>
}
Light Color Skin
Copy
import {
    SendBirdProvider,
    withSendBird,
    sendBirdSelectors,
} from "sendbird-uikit";
import "sendbird-uikit/dist/index.css";

const Welcome = ({ currentUser }) => (
    <div>
        {`Hello, ${currentUser || 'unknown user'}`}
    </div>
);

const WelcomeWithSendBird = withSendBird(Welcome, (state) => {
    const sdk = sendBirdSelectors.getSdk(state);
    const currentUser = sdk && sdk.getCurrentUserId && sdk.getCurrentUserId();
    return ({ currentUser });
});

const GetSdkExample = () => (
    <SendBirdProvider appId={appId} userId={userId} nickname={userId}>
        <WelcomeWithSendBird />
    </SendBirdProvider>
)
Light Color Skin
Copy
// getCreateChannel & getLeaveChannel
import {
    SendBirdProvider,
    withSendBird,
    sendBirdSelectors,
} from "sendbird-uikit";
import "sendbird-uikit/dist/index.css";

const appId = process.env.APP_ID;
const userId = process.env.USER_ID;
const channelUrl = process.env.CHANNEL_URL;

const CustomComponent = ({ createChannel, sdk, leaveChannel }) => {
    const [channelUrl, setChannelUrl] = useState('');
    return(
        <>
            <button onClick={() => {
                let params = new sdk.GroupChannelParams();
                params.isPublic = false;
                params.isEphemeral = false;
                params.isDistinct = false;
                params.addUserIds(['sravan']);
                params.name = NAME;
                createChannel(params)
                    .then(c => {
                        setChannelUrl(c.url);
                    })
                    .catch(c => console.warn(c));
                }}
                > Create channel
            </button>
            <button onClick={() => {
                leaveChannel(channelUrl).
                    then(c => {
                        setChannelUrl('');
                    })
                    .catch(c => console.warn(c));
                }}
                > Leave channel
            </button>
            <br />
            { `Created channel is: ${channelUrl}` }
        </>
    );
};

const CustomComponentWithSendBird = withSendBird(CustomComponent, (state) => {
    const createChannel = sendBirdSelectors.getCreateChannel(state);
    const leaveChannel = sendBirdSelectors.getLeaveChannel(state);
    const sdk = sendBirdSelectors.getSdk(state);
    return ({ createChannel, sdk, leaveChannel });
});

export const ChannelCRUDSelectors = () => (
    <SendBirdProvider appId={appId} userId={userId} nickname={userId}>
        <CustomComponentWithSendBird />
        <div style={{ width: '320px', height: '500px' }}>
            <ChannelList />
        </div>
    </SendBirdProvider>
);
Light Color Skin
Copy
// getSendUserMessage & getSendFileMessage & getDeleteMessage & getUpdateUserMessage
import {
    SendBirdProvider,
    withSendBird,
    sendBirdSelectors,
} from "sendbird-uikit";
import "sendbird-uikit/dist/index.css";

const appId = process.env.APP_ID;
const userId = process.env.USER_ID;
const channelUrl = process.env.CHANNEL_URL;

const CustomComponent = (props) => {
    const {
        sendMessage,
        sendFileMessage,
        deleteMessage,
        updateLastMessage,
        sdk,
    } = props;
    const [lastMessage, setLastMessage] = useState({});
    const lastMessageId = lastMessage.messageId;
    return(
        <div onSubmit={e => e.preventDefault()}>
            {`Last MessageId: ${lastMessageId}`}
            <button onClick={() => {
                const params = new sdk.UserMessageParams();
                params.message = MESSAGE;
                sendMessage(channelUrl, params)
                    .then((pendingMessage) => {
                        setLastMessage(pendingMessage);
                        alert('Message is pending', pendingMessage);
                        return pendingMessage;
                    })
                    .then(message => {
                        alert('Message successfully sent', message);
                        setLastMessage(message);
                        console.warn(message);
                    })
                    .catch(e => {
                        console.warn(e);
                        alert('Couldn\'t send message.');
                    })
                }}
                > Send message
            </button>
            <button disable={!lastMessageId} onClick={() => {
                const params = new sdk.UserMessageParams();
                params.message = UPDATED_MESSAGE;
                updateLastMessage(channelUrl, lastMessageId, params)
                    .then((message) => {
                        setLastMessage(message);
                        alert('Message updated');
                    })
                    .catch(e => alert('Couldn\'t update a message.'))
                }}
                > Update last message
            </button>
            <button disable={!lastMessageId} onClick={() => {
                deleteMessage(channelUrl, lastMessage)
                    .then(() => {
                        alert('Message deleted');
                    })
                    .catch(e => {
                        console.warn(e);
                        alert('Couldn\'t delete a message.')
                    })
                }}
                > Delete last message
            </button>
            <br/>
            <input type="file" id="file-upload" />
            <button onClick={() => {
                const params = new sdk.FileMessageParams();
                params.file = document.getElementById('file-upload').files[0];
                sendFileMessage(channelUrl, params)
                    .then((pendingMessage) => {
                        setLastMessage(pendingMessage);
                        alert('Message is pending', pendingMessage);
                        return pendingMessage;
                    })
                    .then(message => {
                        alert('Message successfully sent', message);
                        setLastMessage(message);
                        console.warn(message);
                    })
                    .catch(e => alert('Couldn\'t delete message.'))
                            }}
                > Send file Message
            </button>
                </div>
        );
};

const CustomComponentWithSendBird = withSendBird(CustomComponent, (state) => {
    const sendMessage = sendBirdSelectors.getSendUserMessage(state);
    const sendFileMessage = sendBirdSelectors.getSendFileMessage(state);
    const deleteMessage = sendBirdSelectors.getDeleteMessage(state);
    const updateLastMessage = sendBirdSelectors.getUpdateUserMessage(state);
    const sdk = sendBirdSelectors.getSdk(state);
    return ({
        sendMessage,
        sendFileMessage,
        deleteMessage,
        updateLastMessage,
        sdk,
    });
});

export const MessageCRUDSelectors = () => (
    <SendBirdProvider appId={appId} userId={userId} nickname={userId}>
        <CustomComponentWithSendBird />
        <div style={{ width: '320px', height: '500px' }}>
            <Channel channelUrl={channelUrl} />
                </div>
    </SendBirdProvider>
);

useSendbirdStateContext

You can use the hook pattern to access the SendbirdProvider's internal state through useSendbirdStateContext. useSendbirdStateContext can be used along with selectors to easily implement various functionalities.

Light Color Skin
Copy
import React, { useEffect, useState } from "react";
import { useSendbirdStateContext, sendBirdSelectors } from "sendbird-uikit";
import { v4 as uuidv4 } from "uuid";
function CustomTypingIndicator(props) {
    const { currentChannelUrl } = props;
    const context = useSendbirdStateContext();
    const sdkInstance = sendBirdSelectors.getSdk(context);
    const sendMessage = sendBirdSelectors.getSendUserMessage(context);
    const [indicator, setIndicator] = useState({
        show: false,
        name: null
    });
    useEffect(() => {
        const uuid = uuidv4();

        if (sdkInstance && sdkInstance.ChannelHandler && currentChannelUrl) {
            const channelHandler = new sdkInstance.ChannelHandler();
            channelHandler.onMessageReceived = (channel, message) => {
                if (channel.url !== currentChannelUrl) {
                    return;
                }
                setIndicator({
                    show: true,
                    name: message.sender
                });
                setTimeout(() => {
                    setIndicator({
                        show: false,
                        name: null
                    });
                }, 2000);
            };
            sdkInstance.addChannelHandler(uuid, channelHandler);
        }

        return () => {
            if (sdkInstance && sdkInstance.removeChannelHandler) {
                sdkInstance.removeChannelHandler(uuid);
            }
        };
    }, [sdkInstance, currentChannelUrl]);
    return (
        <div className="typing-indicator">
            {indicator.show ? `${indicator.name} is typing` : null}
            <button onClick={() => {
                const params = new sdkInstance.UserMessageParams();
                    params.message = "Hello World";
                    sendMessage(channelUrl, params)
                        .then((pendingMessage) => {
                            setLastMessage(pendingMessage);
                            alert('Message sent: pending', pendingMessage);
                            return pendingMessage;
                        })
                        .then(message => {
                            alert('Message sent: success', message);
                            setLastMessage(message);
                            console.warn(message);
                        })
                        .catch(e => {
                            console.warn(e);
                            alert('Couldnt send message');
                        })
            }} />
        </div>
    );
}
export default CustomTypingIndicator;