В этой статье мы разберём как сделать простой чат на React.js, но стоит сказать, что тут не будет показываться как разрабатывать серверную часть, а только сторону клиента.
Если же вы хотите знать как разработать back-end для чата, то почитайте одну из этих статей:
Особенно рекомендую посмотреть про Python и JavaScript.
Чат на React.js:
Всё будет происходить в одном скрипте, и вы легко сможете его адаптировать под свою программу, особенно это касается путей для отправки и получения данных вы легко сможете их изменить.
Также для начала вам стоит установить React.js, мы сделаем это через NPM, введите эту команду:
1 | npm install --save react react-dom |
После этого создайте файл компонента, и первым делом импортируем в него всё что нам надо:
1 2 3 | import React from 'react'; import { w3cwebsocket as W3CWebSocket } from "websocket"; import { Card, CardText, ButtonToggle, Input } from "reactstrap"; |
Как видите мы тут импортировали React, библиотеку W3CWebSocket, для работы с WebSocket, также специальную библиотеку для работы с boostrap в React.
Теперь создаём классовый компонент, делается это примерно так:
1 2 3 4 5 | class Chat extends React.Component { ... } export default Chat; |
Как видите мы этот компонент сразу же экспортируем.
Теперь создадим состояние, для этого уже внутри компонента пишем не большое свойство:
1 2 3 4 | state = { "msgs": [], "msgValue": "", } |
Как видите тут у нас храниться сообщения в массиве msgs
, и значение input
в msgValue
, в остальном тут не чего нет.
Также в конструкторе класса нужно подключиться серверу по WebSocket:
1 2 3 4 5 6 7 8 9 10 | this.slug = this.props.match.params.slug; this.client = new W3CWebSocket('ws://127.0.0.1:8000/ws/chat/' + this.slug + '/'); this.client.onopen = () => { console.log('WebSocket Client Connected'); }; this.client.onmessage = (e) => { this.addMessage(e.data); } |
Первым делом в конструкторе мы берём из пропсов переменную slug
, которая хранит в себе номер чата, который мы берём из URL.
Потом создаём объект класса W3CWebSocket
для работы со сервером с помощью WebSocket и открываем соединение, последние создаём слушателя, который принимает все сообщения от сервера и сразу сообщение кладём его в state
с помощью метода addMessage()
, но о нём чуть ниже.
Теперь создадим два метода, первый для отправки сообщения, а второй для получения этого сообщения:
1 2 3 4 5 6 7 8 | sendMessage = e => { e.preventDefault(); this.client.send(JSON.stringify( { "message": this.state.msgValue, } )); } |
Тут мы просто отправляем сообщение через WebSocket которому мы подключились, но перед этим всё превратили в JSON формат.
Теперь посмотрим метод который на оборот принимает сообщение и кладёт их в state
:
1 2 3 4 5 6 7 8 | addMessage(msg) { let message = JSON.parse(msg); this.setState(state => { let new_msg = [{"text": message.message}] const msgs = new_msg.concat(state.msgs); return {msgs} }) } |
Как вы помните выше, мы передаём в этот метод то что получаем от сервера, а получаем мы от него данные в JSON формате, поэтому в начале мы должны его парсить.
После через setState()
, мы добавляем данные в состояние, но сначала мы создаём массив с одним сообщением, как видите это одно сообщение просто объект, куда мы кладём только текст.
Но это было сделано специально на будущие, таким образом вы можете туда класть например, данные пользователей, их идентификатор или имя, это на ваше усмотрение.
Последние объединяем текущие состояние массива сообщений и с новым, в итоге получаем новый дополненный массив, возвращаем его тем самым меняем состояние.
Примечание:
Так как мы храним данные в объекте, мы должны возвращать тоже в объекте и название переменной должно быть точно таким же, как и у состояния в котором храним сообщение.
Последние осталось разобрать рендеринг, с ним всё гораздо интереснее, так как в нём кроме самого рендеринга, будет не большая логика.
Вот рендер:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | render() { const Messages = [] for (const key in this.state.msgs) { Messages.unshift( <> <Card body> <CardText>{this.state.msgs[key].text}</CardText> </Card> </>) } return ( <div className="chat"> <div className="msgs" id="chat"> {Messages} <div style={{ float:"left", clear: "both" }}></div> </div> <div className="sendMsg row justify-content-between"> <Input type="text" name="msgValue" className="col-xl-9 input-msg" onChange={this.onChange} value={this.defaultIfEmpty(this.state.msgValue)} /> <ButtonToggle className="col-xl-2" color="primary" onClick={this.sendMessage}>Отправить</ButtonToggle> </div> </div> ) }; |
В начале мы тут создаём массив, который будет хранить в себе все сообщения, но уже не просто виде текста или объекта, а виде шаблонов, которые мы будем рендерить.
Через цикл for
мы проходимся по всему массиву состоянию сообщений и кладём их в наш новый массив Messages
, потом его уже выводим и возвращаемом в рендере, также делаем не большой input
и кнопку отправки формы.
Вывод:
В этой статье вы прочитали как сделать чат на React.js, тут конечно только самое основное что нужно знать, но в целом весь код я брал со своего GitHub, ссылка на проект и файл где это использовалась чуть ниже.
Ссылка на файл;
Сcылка на проект;