Рассказываем, как создать собственный чат на React.js с помощью Charset SDK: от создания компонентов до работы со сторонним API.
Шаг 1: раскладываем интерфейс на компоненты
Так как Реакт – компонентный фреймворк, первое, что нам нужно сделать, это представить чат на React как набор элементов.
Начнем с создания корневого компонента – своеобразного холдера для всех остальных элементов приложения:

Красный прямоугольник вокруг макета – корневой элемент, назовем его App.
Теперь нужно разобраться с вопросом: какие дочерние элементы должен содержать чат на React.js? В нашем случае, есть смысл создать три дочерних элемента, которые мы назовем следующим образом:
- Title
- MessageList
- SendMessageForm
Выделим их на макете:

При построении компонентного приложения, необходимо постоянно спрашивать себя: какие еще компоненты может содержать интерфейс? Таким образом, можно создавать более простые составные части для будущих сложных компонентов.
Шаг 2: настраиваем кодовую базу
Для знакомства с фреймворком воспользуемся самым простым путем сборки приложения: просто создадим файл index.html, к которому подключим необходимые библиотеки и код.

Кроме самого Реакта, мы импортируем Charset SDK и Babel, который необходим для преобразования JSX.
Откройте готовый проект в новой вкладке и попробуйте поиграть с кодом, если будете испытывать трудности с пониманием туториала.

Также по ссылке проект можно скачать в виде архива и развернуть на локальном сервере.
Шаг 3: создаем корневой компонент
Когда все необходимые файлы подключены, можно приступать к написанию компонентов. Они будут создаваться в файле index.js.
Начнем с создания основного компонента App. App станет единственным «умным» компонентом нашей системы, так как он будет обрабатывать данные и общаться с API. Его вид в базовом виде (без логики):
class App extends React.Component {
render() {
return (
<div className="app">
<Title />
<MessageList />
<SendMessageForm />
</div>
)
}
}
Сейчас App только рендерит три дочерних компонента: <Title>,<MessageList>, и <SendMessageForm>.
Сообщения чата будут храниться в свойстве state компонента. Таким образом, мы будем иметь доступ к сообщениям через this.state.messages и сможем передавать их во все дочерние элементы чата.
Для начала работы над сообщениями воспользуемся «рыбой», а позже заменим фиктивные сообщения на данные от Chatkit API.
Создадим переменную DUMMY_DATA:
const DUMMY_DATA = [
{
senderId: "perborgen",
text: "who'll win?"
},
{
senderId: "janedoe",
text: "who'll win?"
}
]
Теперь, добавим эти данные в state компонента App и передадим в MessageList как свойство.
class App extends React.Component {
constructor() {
super()
this.state = {
messages: DUMMY_DATA
}
}
render() {
return (
<div className="app">
<MessageList messages={this.state.messages} />
<SendMessageForm />
</div>
)
}
}
Так, мы инициализируем state в конструкторе и передаем this.state.messages компоненту MessageList. Обратите внимание, что мы использовали super(). Необходимо делать это каждый раз, когда вам нужен компонент с запоминанием состояния.
Шаг 4: рендеринг сообщений
Посмотрим, как можно отрисовать сообщения в компоненте MessageList:
class MessageList extends React.Component {
render() {
return (
<ul className="message-list">
{this.props.messages.map(message => {
return (
<li key={message.id}>
<div>
{message.senderId}
</div>
<div>
{message.text}
</div>
</li>
)
})}
</ul>
)
}
}
Это так называемый «глупый» компонент. Он принимает единственное свойство messages, которое содержит массив объектов. Затем, он просто рендерит свойства text и senderId из этих объектов.
В нашем случае, рендер будет выглядеть следующим образом:

Теперь у нас есть каркас приложения, и мы можем рендерить сообщения. Заменим фиктивные сообщения на настоящие.
Шаг 5: получаем API-ключ для Chatkit
Chatkit – это инструмент для быстрого создания пользовательских чатов внутри существующих приложений. Чтобы начать с ним работу, нам нужно получить доступ к API сервиса.
Начнем с регистрации аккаунта.

В работе нам понадобится 4 значения из личного кабинета:
- Instance Locator
- Test Token Provider
- Room id
- Username
Instance Locator:

Чуть ниже находится Test Token Provider:

Следующим шагом нужно создать User и Room, что делается на той же странице. В первую очередь необходимо создать пользователя, потом можно будет создать комнату и получить ее id.

Шаг 6: рендерим настоящий чат на React
Теперь вернемся в index.js и сохраним полученные идентификаторы в виде переменных. Пример выглядит так:
const instanceLocator = "v1:us1:dfaf1e22-2d33-45c9-b4f8-31f634621d24" const testToken = "https://us1.pusherplatform.io/services/chatkit_token_provider/v1/ dfaf1e22-2d33-45c9-b4f8-31f634621d24/token" const username = "perborgen" const roomId = 9796712
С этими данными мы готовы подключиться к Chatkit. Это будет происходить в методе componentDidMount компонента App.
В первую очередь создаем ChatManager:
componentDidMount() {
const chatManager = new Chatkit.ChatManager({
instanceLocator: instanceLocator,
userId: username,
tokenProvider: new Chatkit.TokenProvider({
url: testToken
})
})
Затем вызовем chatManager.connect(), чтобы подключиться к API:
chatManager.connect().then(currentUser => {
currentUser.subscribeToRoom({
roomId: roomId,
hooks: {
onNewMessage: message => {
this.setState({
messages: [...this.state.messages, message]
})
}
}
})
})
}
Так мы получим доступ к объекту currentUser, который послужит интерфейсом для взаимодействия с API. Поскольку с currentUser нам еще предстоит работать, сохраним его в this.currentUser = currentUser.
Дальше мы вызываем currentUser.subscribeToRoom() и передаем наш roomId в хук onNewMessage. Хук срабатывает каждый раз, когда сообщение передается в комнату, и в этот момент мы просто передаем новое сообщение в конец this.state.messages.
Так будет выглядеть результат наших последних действий после рендера:

Шаг 7: обрабатываем пользовательский ввод
Теперь нам нужно создать компонент SendMessageForm. SendMessageForm будет так называемым «контролируемым» компонентом. Это значит, что данный компонент контролирует рендер в поле ввода через свой state.
Рассмотрим метод render():
class SendMessageForm extends React.Component {
render() {
return (
<form
className="send-message-form">
<input
onChange={this.handleChange}
value={this.state.message}
placeholder="Type your message and hit ENTER"
type="text" />
</form>
)
}
}
Здесь мы делаем две вещи:
- Следим за пользовательским вводом с помощью onChange, благодаря которому можем инициировать метод handleChange.
- Устанавливаем значение value поля ввода используя this.state.message.
Эти два действия соединяются в методе handleChange. Он просто обновляет состояние в соответствии с тем, что ввел пользователь:
handleChange(e) {
this.setState({
message: e.target.value
})
}
Затем страница перерисовывается, и поскольку поле ввода задано явно из состояния с использованием value={this.state.message}, оно будет обновляться.
Теперь дадим компоненту конструктор. В нем мы инициализируем state и привяжем к this метод handleChange:
constructor() {
super()
this.state = {
message: ''
}
this.handleChange = this.handleChange.bind(this)
}
Привязка handleChange нужна затем, чтобы мы могли получить доступ к this внутри этого метода.
Шаг 8: отправка сообщений
Компонент SendMessageForm почти завершен, осталось только позаботиться об отправке данных. Для этого мы будем вызывать обработчик handleSubmit при onSubmit компонента формы.
render() {
return (
<form
onSubmit={this.handleSubmit}
className="send-message-form">
<input
onChange={this.handleChange}
value={this.state.message}
placeholder="Type your message and hit ENTER"
type="text" />
</form>
)
}
Чтобы отправить нужные данные, делаем следующее:
handleSubmit(e) {
e.preventDefault()
this.props.sendMessage(this.state.message)
this.setState({
message: ''
})
}
Здесь мы вызвали sendMessage и передали ему this.state.message в качестве параметра. Мы еще не создали метод sendMessage, но займемся этим в следующем шаге, так как это метод компонента App.
SendMessageForm целиком выглядит следующим образом:
class SendMessageForm extends React.Component {
constructor() {
super()
this.state = {
message: ''
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(e) {
this.setState({
message: e.target.value
})
}
handleSubmit(e) {
e.preventDefault()
this.props.sendMessage(this.state.message)
this.setState({
message: ''
})
}
render() {
return (
<form
onSubmit={this.handleSubmit}
className="send-message-form">
<input
onChange={this.handleChange}
value={this.state.message}
placeholder="Type your message and hit ENTER"
type="text" />
</form>
)
}
}
Шаг 9: отправка сообщений в Chatkit
Приложение готово к отправке сообщений в Chatkit. Это будет происходить в компоненте App, в котором мы создадим метод this.sendMessage:
sendMessage(text) {
this.currentUser.sendMessage({
text,
roomId: roomId
})
}
Метод принимает один параметр (текст сообщения). Передадим его в качестве свойства в <SendMessageForm>:
render() {
return (
<div className="app">
<Title />
<MessageList messages={this.state.messages} />
<SendMessageForm sendMessage={this.sendMessage} />
)
}
Шаг 10: компонент Title
Завершим чат на React, создав компонент для отображения заголовка. Это простой функциональный компонент:
function Title() {
return <p class="title">My awesome chat app</p>
}

Вот и все, теперь у вас есть собственный мессенджер! Еще раз напомним: если у вас возникнут трудности с пониманием материала, попробуйте поиграть с кодом на Scrimba, чтобы лучше разобраться в деталях уже работающего приложения.
Комментарии