In diesem Tutorial lernen Sie, wie Sie eine Chat -App mit React und Chatkit erstellen.
Wenn wir fertig sind, haben wir eine Chat -Anwendung mit Tippindikatoren , einer "Who's Online" -Liste und einem Nachrichtenverlauf :

Wenn Sie der Meinung sind, dass dies in einem Tutorial viel zu tun hat, hätten Sie normalerweise Recht!
Da wir Chatkit jedoch verwenden, können wir uns mehr oder weniger ausschließlich auf den Front-End-React-Code konzentrieren, während Chatkit das starke Heben durchführt.
Chatkit ist eine gehostete API, mit der Sie beeindruckende Chat -Funktionen in Ihre Anwendungen mit weniger Code aufbauen können. Funktionen wie,
Mit unseren plattformübergreifenden SDKs werden alle Chat-Daten an unsere gehostete API gesendet, in der wir den Chat-Status verwalten und an Ihre Kunden senden:

Sie müssen sich nie um Skalen oder Infrastruktur sorgen, wir kümmern uns um alles für Sie.
Vielleicht ist der beste Weg, um Chatkit zu lernen, mit dem Bauen zu beginnen. Ich empfehle Ihnen, Ihnen zu folgen. Unterwegs lernen Sie Best Practices, wenn Sie Chatkit mit React verwenden.
Dieses Tutorial wurde geschrieben, damit Sie Schritt für Schritt folgen können. Insgesamt gibt es 12 Schritte.
Hier ist ein kurzer Überblick, damit Sie wissen, was Sie erwarten können:
Okay, lass uns codieren!
Anstatt von absoluter Kratzer zu beginnen, basiert diese Vorgehensweise auf einer minimalen Starter -Vorlage:

Wie Sie sehen können, enthält die Startervorlage keine interessante Logik - nur Kesselplatte Wir müssen eine React -Anwendung und einen einfachen Knotenserver ausführen.
"Server? Niemand hat einen Server erwähnt!"
Wenn Sie mit dem Knoten nicht allzu vertraut sind, mach dir keine Sorgen? Nach dem nächsten Abschnitt müssen wir den Server nicht berühren.
Laden Sie, um die Starter -Vorlage zu starten, und führen Sie npm install aus:
git clone https://github.com/pusher/build-a-slack-clone-with-react-and-pusher-chatkit chatkit-tutorial
cd chatkit-tutorial
npm install
(Hinweis: Um den ausgefüllten Code anzuzeigen, können Sie die completed Filiale anzeigen oder git checkout complete lokal ausführen.)
(ANMERKUNG: In diesem Tutorial wird die Verwendung von npm verwendet, aber die äquivalenten yarn funktionieren ebenfalls.)
Jetzt haben Sie die Starter -Vorlage heruntergeladen. Lassen Sie uns eine Chatkit -Instanz erstellen.
Um eine eigene Chatkit -Instanz zu erstellen, besuchen Sie das Dashboard und klicken Sie auf Neue: Neu :

Geben Sie Ihrer Instanz einen Namen (ich nannte mein "React Chat -Tutorial") und beachten Sie dann Ihren Instanz -Locator und Ihre geheime Schlüssel in der Registerkarte Tasten. Wir brauchen sie beide im nächsten Abschnitt.
Während die meisten Interaktionen im Client stattfinden, benötigt Chatkit auch ein Server -Gegenstück, um Benutzer sicher zu erstellen und zu verwalten:

Wir werden die Benutzer in diesem Tutorial nicht authentifizieren, aber wir müssen trotzdem eine Route definieren, die bei einem Anruf einen Chatkit -Benutzer erstellt.
Beginnen Sie mit der Installation von @pusher/chatkit-server :
npm install --save @pusher/chatkit-server
Dann aktualisieren Sie ./server.js :
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
+ const Chatkit = require('@pusher/chatkit-server')
const app = express()
+ const chatkit = new Chatkit.default({
+ instanceLocator: 'YOUR INSTANCE LOCATOR',
+ key: 'YOUR KEY',
+ })
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(cors())
+ app.post('/users', (req, res) => {
+ const { username } = req.body
+ chatkit
+ .createUser({
+ id: username,
+ name: username
+ })
+ .then(() => res.sendStatus(201))
+ .catch(error => {
+ if (error.error === 'services/chatkit/user_already_exists') {
+ res.sendStatus(200)
+ } else {
+ res.status(error.status).json(error)
+ }
+ })
+ })
+ app.post('/authenticate', (req, res) => {
+ const authData = chatkit.authenticate({ userId: req.query.user_id })
+ res.status(authData.status).send(authData.body)
+ })
const PORT = 3001
app.listen(PORT, err => {
if (err) {
console.error(err)
} else {
console.log(`Running on port ${PORT}`)
}
})Denken Sie daran , "Ihren Instanz -Locator" und "Ihren Schlüssel" durch Ihre eigenen Werte zu ersetzen.
Hier gibt es viel zu entpacken, angefangen von oben:
Chatkit von @pusher/chatkit-serverchatkit -Instanz mit dem Instanz -Locator und dem Schlüssel , den wir im vorherigen Schritt festgestellt haben/users nehmen wir einen username und erstellen einen Chatkit -Benutzer über unsere chatkit -Instanz/authenticate , um sie zu authentifizieren. Der Server muss mit einem Token (zurückgegeben von chatkit.authenticate ) antworten, wenn die Anforderung gültig ist. In unserem Fall werden wir - naiv - annehmen, dass jeder, der sie sagen, und ein Token von chatkit.authenticate zurückgeben. Authenticate, egal was passiert.Boom?! Das ist alles, was wir auf dem Server tun müssen. Gehen wir mit dem Kunden weiter ...
Wenn jemand die App lädt, möchten wir ihn fragen, wer er ist.
Sobald sie eingereichert sind, senden wir ihren Benutzernamen an den Server (an die gerade definierte Route /users ) und erstellen einen Chatkit -Benutzer, wenn es nicht vorhanden ist.
Um den Namen des Benutzers zu sammeln, erstellen Sie eine Komponente namens UsernameForm.js in in ./src/components/ :
+ import React, { Component } from 'react'
+ class UsernameForm extends Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ username: '',
+ }
+ this.onSubmit = this.onSubmit.bind(this)
+ this.onChange = this.onChange.bind(this)
+ }
+ onSubmit(e) {
+ e.preventDefault()
+ this.props.onSubmit(this.state.username)
+ }
+ onChange(e) {
+ this.setState({ username: e.target.value })
+ }
+
+ render() {
+ return (
+ <div>
+ <div>
+ <h2>What is your username?</h2>
+ <form onSubmit={this.onSubmit}>
+ <input
+ type="text"
+ placeholder="Your full name"
+ onChange={this.onChange}
+ />
+ <input type="submit" />
+ </form>
+ </div>
+ </div>
+ )
+ }
+ }
+
+ export default UsernameForm Dann App.js aktualisieren:
import React, { Component } from 'react'
+ import UsernameForm from './components/UsernameForm'
class App extends Component {
+ constructor() {
+ super()
+ this.state = {
+ currentUsername: '',
+ }
+ this.onUsernameSubmitted = this.onUsernameSubmitted.bind(this)
+ }
+ onUsernameSubmitted(username) {
+ fetch('http://localhost:3001/users', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ username }),
+ })
+ .then(response => {
+ this.setState({
+ currentUsername: username
+ })
+ })
+ .catch(error => console.error('error', error))
+ }
render() {
- return <h1>Chatly</h1>
+ return <UsernameForm onSubmit={this.onUsernameSubmitted} />
}
}
export default App Führen Sie die Anwendung mit npm start aus und Sie werden feststellen, dass der Bildschirm gerendert wird:

Ausgehend von App.js :
UsernameForm -Komponente. Es sieht Ihnen wahrscheinlich bekannt vor, da es ein gemeinsames React -Muster verwendet, das als kontrollierte Komponenten bezeichnet wird. Weitere Informationen zu React -Formularen finden Sie hierrender machen wir die UsernameForm und verbinden den Ereignishandler onUsernameSubmittedonUsernameSubmitted aufgerufen wird, senden wir eine Postanforderung an die gerade definierte Route /users . Wenn die Anfrage erfolgreich ist, aktualisieren wir this.state.currentUsername , damit wir sie später verweisen können. Andernfalls console.error wir den Fehler Im Moment rendern wir die UsernameForm und es nimmt den gesamten Bildschirm ein (siehe oben).
Sobald der Benutzername eingereicht wurde, möchten wir zu einem anderen Bildschirm wechseln - nämlich den Chat -Bildschirm.
Zu diesem Zweck müssen wir zunächst eine ChatScreen.js -Komponente in ./src erstellen:
+ import React, { Component } from 'react'
+
+ class ChatScreen extends Component {
+ render() {
+ return (
+ <div>
+ <h1>Chat</h1>
+ </div>
+ )
+ }
+ }
+
+ export default ChatScreen Dann App.js aktualisieren:
import React, { Component } from 'react'
import UsernameForm from './components/UsernameForm'
+ import ChatScreen from './ChatScreen'
class App extends Component {
constructor() {
super()
this.state = {
currentUsername: '',
+ currentScreen: 'WhatIsYourUsernameScreen'
}
this.onUsernameSubmitted = this.onUsernameSubmitted.bind(this)
}
onUsernameSubmitted(username) {
fetch('http://localhost:3001/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username }),
})
.then(response => {
this.setState({
currentUsername: username,
+ currentScreen: 'ChatScreen'
})
})
.catch(error => console.error('error', error))
}
render() {
+ if (this.state.currentScreen === 'WhatIsYourUsernameScreen') {
return <UsernameForm onSubmit={this.onUsernameSubmitted} />
+ }
+ if (this.state.currentScreen === 'ChatScreen') {
+ return <ChatScreen currentUsername={this.state.currentUsername} />
+ }
}
}
export default App Anstatt einen Router zu verwenden, rendern wir den Bildschirm basierend auf this.state.currentScreen .
Zuvor haben wir @pusher/chatkit-server installiert. Jetzt sind wir im Client-Land, Sie müssen auch @pusher/chatkit-client installieren:
npm install --save @pusher/chatkit-client
Dann aktualisieren Sie ChatScreen.js :
import React, { Component } from 'react'
+ import Chatkit from '@pusher/chatkit-client'
class ChatScreen extends Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ currentUser: {}
+ }
+ }
+ componentDidMount () {
+ const chatManager = new Chatkit.ChatManager({
+ instanceLocator: 'YOUR INSTANCE LOCATOR',
+ userId: this.props.currentUsername,
+ tokenProvider: new Chatkit.TokenProvider({
+ url: 'http://localhost:3001/authenticate',
+ }),
+ })
+
+ chatManager
+ .connect()
+ .then(currentUser => {
+ this.setState({ currentUser })
+ })
+ .catch(error => console.error('error', error))
+ }
render() {
return (
<div>
<h1>Chat</h1>
</div>
)
}
}
export default ChatScreenDenken Sie daran, "Ihren Instanz -Locator" durch Ihre zu ersetzen, die Sie zuvor festgestellt haben.
Nochmals von oben angefangen:
ChatkitChatManager mit unserem instanceLocator userId (von this.props.currentUsername ) und einem benutzerdefinierten TokenProvider . Der TokenProvider verweist auf die zuvor definierte Route /authenticateChatManager initialisiert wurde, können wir connect anrufen. connect geschieht asynchron und ein Promise wird zurückgegeben. Wenn Sie diesen Schritten genau befolgt haben, werden Sie eine Verbindung herstellen. Achten Sie jedoch darauf auf eine console.error S, falls Sie etwas verpasst haben Bei der Verwendung von Chatkit werden alle Nachrichten an einen Chatkit -Raum gesendet.
Zimmer können programmgesteuert (auf dem Server oder Client mit createRoom ) oder im Dashboard -Inspektor erstellt werden.
Das Erstellen von Räumen aus dem Inspektor ist keine gute Praxis (es ist hauptsächlich zum Testen bestimmt), aber für den Zweck dieses Vorgangs werden wir es trotzdem tun.
Gehen Sie im Dashboard zur Registerkarte Konsole , wo Sie den Inspektor finden und einen Benutzer mit jedem Namen erstellen. Ich werde meinen "Admin" nennen.
Erstellen Sie dann einen Raum namens "General":

Es ist wirklich wichtig, die oben hervorgehobene eindeutige Raum -ID zu beachten.
Dieser Schritt markiert einen erheblichen Punkt in der Vorgehensweise.
Jetzt haben wir unsere Kesselplatte und können schnell Chat -Funktionen erstellen.
In Zukunft zerlegen wir jede Funktion in unabhängige (wiederverwendbar, wenn Sie möchten!) Reagierenkomponenten:

Wir werden jede Komponente im Laufe der Zeit erstellen, aber um das Tutorial etwas einfacher zu befolgen, lassen Sie uns jetzt das Grundkomponenten -UI -Layout angeben:
import React, { Component } from 'react'
import Chatkit from '@pusher/chatkit-client'
class ChatScreen extends Component {
constructor(props) {
super(props)
this.state = {
currentUser: {}
}
}
componentDidMount () {
const chatManager = new Chatkit.ChatManager({
instanceLocator: 'YOUR INSTANCE LOCATOR',
userId: this.props.currentUsername,
tokenProvider: new Chatkit.TokenProvider({
url: 'http://localhost:3001/authenticate',
}),
})
chatManager
.connect()
.then(currentUser => {
this.setState({ currentUser })
})
.catch(error => console.error('error', error))
}
render() {
- return (
- <div>
- <h1>Chat</h1>
- </div>
- )
+ const styles = {
+ container: {
+ height: '100vh',
+ display: 'flex',
+ flexDirection: 'column',
+ },
+ chatContainer: {
+ display: 'flex',
+ flex: 1,
+ },
+ whosOnlineListContainer: {
+ width: '300px',
+ flex: 'none',
+ padding: 20,
+ backgroundColor: '#2c303b',
+ color: 'white',
+ },
+ chatListContainer: {
+ padding: 20,
+ width: '85%',
+ display: 'flex',
+ flexDirection: 'column',
+ },
+ }
+ return (
+ <div style={styles.container}>
+ <div style={styles.chatContainer}>
+ <aside style={styles.whosOnlineListContainer}>
+ <h2>Who's online PLACEHOLDER</h2>
+ </aside>
+ <section style={styles.chatListContainer}>
+ <h2>Chat PLACEHOLDER</h2>
+ </section>
+ </div>
+ </div>
+ )
}
}
export default ChatScreenWenn Sie jetzt die App ausführen, wird das grundlegende Layout stattfinden:

Eindrucksvoll!
Ich freue mich sehr, Ihnen das zu zeigen!
Jetzt haben wir eine Chatkit -Verbindung, das Erstellen von Chat -Funktionen werden so einfach wie die Anschließen von Chatkit -Ereignissen an UI -Komponenten. Hier, lassen Sie mich es Ihnen zeigen.
Erstellen Sie zunächst eine staatenlose MessageList.js -Komponente in ./src/components :
+ import React, { Component } from 'react'
+
+ class MessagesList extends Component {
+ render() {
+ const styles = {
+ container: {
+ overflowY: 'scroll',
+ flex: 1,
+ },
+ ul: {
+ listStyle: 'none',
+ },
+ li: {
+ marginTop: 13,
+ marginBottom: 13,
+ },
+ senderUsername: {
+ fontWeight: 'bold',
+ },
+ message: { fontSize: 15 },
+ }
+ return (
+ <div
+ style={{
+ ...this.props.style,
+ ...styles.container,
+ }}
+ >
+ <ul style={styles.ul}>
+ {this.props.messages.map((message, index) => (
+ <li key={index} style={styles.li}>
+ <div>
+ <span style={styles.senderUsername}>{message.senderId}</span>{' '}
+ </div>
+ <p style={styles.message}>{message.text}</p>
+ </li>
+ ))}
+ </ul>
+ </div>
+ )
+ }
+ }
+
+ export default MessagesList Dann aktualisieren Sie ChatScreen.js :
import React, { Component } from 'react'
import Chatkit from '@pusher/chatkit-client'
+ import MessageList from './components/MessageList'
class ChatScreen extends Component {
constructor(props) {
super(props)
this.state = {
currentUser: {},
+ currentRoom: {},
+ messages: []
}
}
componentDidMount () {
const chatManager = new Chatkit.ChatManager({
instanceLocator: 'YOUR INSTANCE LOCATOR',
userId: this.props.currentUsername,
tokenProvider: new Chatkit.TokenProvider({
url: 'http://localhost:3001/authenticate',
}),
})
chatManager
.connect()
.then(currentUser => {
this.setState({ currentUser })
+ return currentUser.subscribeToRoom({
+ roomId: "YOUR ROOM ID",
+ messageLimit: 100,
+ hooks: {
+ onMessage: message => {
+ this.setState({
+ messages: [...this.state.messages, message],
+ })
+ },
+ },
+ })
+ })
+ .then(currentRoom => {
+ this.setState({ currentRoom })
+ })
.catch(error => console.error('error', error))
}
render() {
const styles = {
...
}
return (
<div style={styles.container}>
<div style={styles.chatContainer}>
<aside style={styles.whosOnlineListContainer}>
<h2>Who's online PLACEHOLDER</h2>
</aside>
<section style={styles.chatListContainer}>
- <h2>Chat PLACEHOLDER</h2>
+ <MessageList
+ messages={this.state.messages}
+ style={styles.chatList}
+ />
</section>
</div>
</div>
)
}
}
export default ChatScreenDenken Sie daran, Ihre Zimmer -ID durch Ihre eigene Zimmer -ID zu ersetzen, die Sie zuvor festgestellt haben.
Lassen Sie es uns aufschlüsseln:
currentUser Objekt, das den aktuellen verbundenen Benutzer darstelltcurrentUser "currentUser (CurrentUser.SubsCressoroom) subscribeToRoom ( currentUser.subscribeToRoom ).subscribeToRoom nimmt einen Ereignis-Handler mit dem Namen onMessage , der jedes Mal in Echtzeit aufgerufen wird, wenn eine neue Nachricht eingehtmessageLimit auf 100 angegeben haben, wird onMessage auch für bis zu 100 neueste Nachrichten rückwirkend bezeichnet. In der Praxis bedeutet dies, dass Sie, wenn Sie die Seite aktualisieren, bis zu 100 der neuesten Chat -Nachrichten angezeigt werdenWir sind auf einer Rolle!
Als nächstes können wir Benutzern Nachrichten senden, indem er zuerst eine SendMessageForm.js -Komponente in ./src/components erstellt:
+ import React, { Component } from 'react'
+
+ class SendMessageForm extends Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ text: '',
+ }
+ this.onSubmit = this.onSubmit.bind(this)
+ this.onChange = this.onChange.bind(this)
+ }
+
+ onSubmit(e) {
+ e.preventDefault()
+ this.props.onSubmit(this.state.text)
+ this.setState({ text: '' })
+ }
+
+ onChange(e) {
+ this.setState({ text: e.target.value })
+ if (this.props.onChange) {
+ this.props.onChange()
+ }
+ }
+
+ render() {
+ const styles = {
+ container: {
+ padding: 20,
+ borderTop: '1px #4C758F solid',
+ marginBottom: 20,
+ },
+ form: {
+ display: 'flex',
+ },
+ input: {
+ color: 'inherit',
+ background: 'none',
+ outline: 'none',
+ border: 'none',
+ flex: 1,
+ fontSize: 16,
+ },
+ }
+ return (
+ <div style={styles.container}>
+ <div>
+ <form onSubmit={this.onSubmit} style={styles.form}>
+ <input
+ type="text"
+ placeholder="Type a message here then hit ENTER"
+ onChange={this.onChange}
+ value={this.state.text}
+ style={styles.input}
+ />
+ </form>
+ </div>
+ </div>
+ )
+ }
+ }
+
+ export default SendMessageForm Dann - Sie haben es erraten - aktualisieren Sie ChatScreen.js :
import React, { Component } from 'react'
import Chatkit from '@pusher/chatkit-client'
import MessageList from './components/MessageList'
+ import SendMessageForm from './components/SendMessageForm'
class ChatScreen extends Component {
constructor(props) {
super(props)
this.state = {
currentUser: {},
currentRoom: {},
messages: []
}
+ this.sendMessage = this.sendMessage.bind(this)
}
+ sendMessage(text) {
+ this.state.currentUser.sendMessage({
+ text,
+ roomId: this.state.currentRoom.id,
+ })
+ }
componentDidMount () {
const chatManager = new Chatkit.ChatManager({
instanceLocator: 'YOUR INSTANCE LOCATOR',
userId: this.props.currentUsername,
tokenProvider: new Chatkit.TokenProvider({
url: 'http://localhost:3001/authenticate',
}),
})
chatManager
.connect()
.then(currentUser => {
this.setState({ currentUser })
return currentUser.subscribeToRoom({
roomId: YOUR ROOM ID,
messageLimit: 100,
hooks: {
onMessage: message => {
this.setState({
messages: [...this.state.messages, message],
})
},
},
})
})
.then(currentRoom => {
this.setState({ currentRoom })
})
.catch(error => console.error('error', error))
}
render() {
const styles = {
...
}
return (
<div style={styles.container}>
<div style={styles.chatContainer}>
<aside style={styles.whosOnlineListContainer}>
<h2>Who's online PLACEHOLDER</h2>
</aside>
<section style={styles.chatListContainer}>
<MessageList
messages={this.state.messages}
style={styles.chatList}
/>
+ <SendMessageForm onSubmit={this.sendMessage} />
</section>
</div>
</div>
)
}
}
export default ChatScreen Die SendMessageForm -Komponente ist im Wesentlichen die gleiche wie die zuvor definierte WhatIsYourUsernameForm -Komponente.
Wenn die SendMessageForm eingereicht wird currentUser greifen wir this.state.currentUser zu sendMessage
Sie können wahrscheinlich ein Muster sehen ...
ChatScreen ist eine Containerkomponente , die unseren Anwendungszustand verwaltet und die Benutzeroberfläche mithilfe von Präsentations- - Normalerweise staatenlosen - Komponenten macht. Der größte Teil unseres Codes beinhaltet das Anschließen von Chatkit -Ereignissen und ihre zugehörigen Daten, um UI -Komponenten zu reagieren.
Wenn Sie jemals versucht haben, Ihre eigenen Tippindikatoren zu implementieren, wissen Sie, dass es schwierig sein kann. Im Allgemeinen bedeuten mehr Echtzeit-Funktionen mehr Daten und mehr Verbindungen zum Verwalten.
Mit Chatkit können Sie Tippindikatoren mit wenig Aufwand hinzufügen.
Beginnen Sie mit der Erstellung einer TypingIndicator.js -Komponente in ./src/components :
+ import React, { Component } from 'react'
+
+ class TypingIndicator extends Component {
+ render() {
+ if (this.props.usersWhoAreTyping.length > 0) {
+ return (
+ <div>
+ {`${this.props.usersWhoAreTyping
+ .slice(0, 2)
+ .join(' and ')} is typing`}
+ </div>
+ )
+ }
+ return <div />
+ }
+ }
+
+ export default TypingIndicator Dann aktualisieren Sie ChatScreen.js :
import React, { Component } from 'react'
import Chatkit from '@pusher/chatkit-client'
import MessageList from './components/MessageList'
import SendMessageForm from './components/SendMessageForm'
+ import TypingIndicator from './components/TypingIndicator'
class ChatScreen extends Component {
constructor(props) {
super(props)
this.state = {
currentUser: {},
currentRoom: {},
messages: [],
+ usersWhoAreTyping: [],
}
this.sendMessage = this.sendMessage.bind(this)
+ this.sendTypingEvent = this.sendTypingEvent.bind(this)
}
+ sendTypingEvent() {
+ this.state.currentUser
+ .isTypingIn({ roomId: this.state.currentRoom.id })
+ .catch(error => console.error('error', error))
+ }
sendMessage(text) {
this.state.currentUser.sendMessage({
text,
roomId: this.state.currentRoom.id,
})
}
componentDidMount() {
const chatManager = new Chatkit.ChatManager({
instanceLocator: 'YOUR INSTANCE LOCATOR',
userId: this.props.currentUsername,
tokenProvider: new Chatkit.TokenProvider({
url: 'http://localhost:3001/authenticate',
}),
})
chatManager
.connect()
.then(currentUser => {
this.setState({ currentUser })
return currentUser.subscribeToRoom({
roomId: YOUR ROOM ID,
messageLimit: 100,
hooks: {
onMessage: message => {
this.setState({
messages: [...this.state.messages, message],
})
},
+ onUserStartedTyping: user => {
+ this.setState({
+ usersWhoAreTyping: [...this.state.usersWhoAreTyping, user.name],
+ })
+ },
+ onUserStoppedTyping: user => {
+ this.setState({
+ usersWhoAreTyping: this.state.usersWhoAreTyping.filter(
+ username => username !== user.name
+ ),
+ })
+ },
},
})
})
.then(currentRoom => {
this.setState({ currentRoom })
})
.catch(error => console.error('error', error))
}
render() {
const styles = {
...
}
return (
<div style={styles.container}>>
<div style={styles.chatContainer}>
<aside style={styles.whosOnlineListContainer}>
<h2>Who's online PLACEHOLDER</h2>
</aside>
<section style={styles.chatListContainer}>
<MessageList
messages={this.state.messages}
style={styles.chatList}
/>
+ <TypingIndicator usersWhoAreTyping={this.state.usersWhoAreTyping} />
<SendMessageForm
onSubmit={this.sendMessage}
+ onChange={this.sendTypingEvent}
/>
</section>
</div>
</div>
)
}
}
export default ChatScreenBei der Verwendung von Chatkit sind die Tippindikatoren auf zwei grundlegende Aktionen zurückzuführen:
currentUser.userIsTyping Wenn der aktuelle Benutzer mit dem Eingeben beginnt; Dann,userStartedTyping und userStoppedTyping -Ereignissen anUnd das ist so ziemlich es.
"Aber Alex, was ist, wenn der Benutzer aufhört , einzugeben?"
Das ist eine sehr gute Frage.
Chatkit ist so intelligent. Wenn der Dienst nach wenigen Sekunden kein userIsTyping erhält, wird davon ausgegangen, dass der currentUser Tipp gestoppt hat. Daher müssen ein Ereignis manuell manuell ansteigern, wenn jemand aufhört, einzugeben. Ziemlich schick, oder?
Kannst du den Schwung spüren? Fast jetzt fertig?
Um die Chat-App zu beenden, verwenden wir die Funktion "Who's's Online" von Chatkit, um eine Liste von Benutzern und ihren Echtzeit-Online-Status zu machen.
Erstellen Sie zunächst eine WhosOnlineList.js -Komponente in /src/components :
+ import React, { Component } from 'react'
+
+ class WhosOnlineList extends Component {
+ renderUsers() {
+ return (
+ <ul>
+ {this.props.users.map((user, index) => {
+ if (user.id === this.props.currentUser.id) {
+ return (
+ <WhosOnlineListItem key={index} presenceState="online">
+ {user.name} (You)
+ </WhosOnlineListItem>
+ )
+ }
+ return (
+ <WhosOnlineListItem key={index} presenceState={user.presence.state}>
+ {user.name}
+ </WhosOnlineListItem>
+ )
+ })}
+ </ul>
+ )
+ }
+
+ render() {
+ if (this.props.users) {
+ return this.renderUsers()
+ } else {
+ return <p>Loading...</p>
+ }
+ }
+ }
+
+ class WhosOnlineListItem extends Component {
+ render() {
+ const styles = {
+ li: {
+ display: 'flex',
+ alignItems: 'center',
+ marginTop: 5,
+ marginBottom: 5,
+ paddingTop: 2,
+ paddingBottom: 2,
+ },
+ div: {
+ borderRadius: '50%',
+ width: 11,
+ height: 11,
+ marginRight: 10,
+ },
+ }
+ return (
+ <li style={styles.li}>
+ <div
+ style={{
+ ...styles.div,
+ backgroundColor:
+ this.props.presenceState === 'online' ? '#539eff' : '#414756',
+ }}
+ />
+ {this.props.children}
+ </li>
+ )
+ }
+ }
+
+ export default WhosOnlineList Dann - zum letzten Mal? - ChatScreen.js aktualisieren:
import React, { Component } from 'react'
import Chatkit from '@pusher/chatkit-client'
import MessageList from './components/MessageList'
import SendMessageForm from './components/SendMessageForm'
import TypingIndicator from './components/TypingIndicator'
+ import WhosOnlineList from './components/WhosOnlineList'
class ChatScreen extends Component {
constructor(props) {
super(props)
this.state = {
currentUser: {},
currentRoom: {},
messages: [],
usersWhoAreTyping: [],
}
this.sendMessage = this.sendMessage.bind(this)
this.sendTypingEvent = this.sendTypingEvent.bind(this)
}
sendTypingEvent() {
this.state.currentUser
.isTypingIn(this.state.currentRoom.id)
.catch(error => console.error('error', error))
}
sendMessage(text) {
this.state.currentUser.sendMessage({
text,
roomId: this.state.currentRoom.id,
})
}
comonentDidMount() {
const chatManager = new Chatkit.ChatManager({
instanceLocator: 'YOUR INSTANCE LOCATOR',
userId: this.props.currentUsername,
tokenProvider: new Chatkit.TokenProvider({
url: 'http://localhost:3001/authenticate',
}),
})
chatManager
.connect()
.then(currentUser => {
this.setState({ currentUser })
return currentUser.subscribeToRoom({
roomId: YOUR ROOM ID,
messageLimit: 100,
hooks: {
newMessage: message => {
this.setState({
messages: [...this.state.messages, message],
})
},
userStartedTyping: user => {
this.setState({
usersWhoAreTyping: [...this.state.usersWhoAreTyping, user.name],
})
},
userStoppedTyping: user => {
this.setState({
usersWhoAreTyping: this.state.usersWhoAreTyping.filter(
username => username !== user.name
),
})
},
+ onPresenceChange: () => this.forceUpdate(),
},
})
})
.then(currentRoom => {
this.setState({ currentRoom })
})
.catch(error => console.error('error', error))
}
render() {
const styles = {
...
}
return (
<div style={styles.container}>
<header style={styles.header}>
<h2>Chatly</h2>
</header>
<div style={styles.chatContainer}>
<aside style={styles.whosOnlineListContainer}>
- <h2>Who's online PLACEHOLDER</h2>
+ <WhosOnlineList
+ currentUser={this.state.currentUser}
+ users={this.state.currentRoom.users}
+ />
</aside>
<section style={styles.chatListContainer}>
<MessageList
messages={this.state.messages}
style={styles.chatList}
/>
<TypingIndicator usersWhoAreTyping={this.state.usersWhoAreTyping} />
<SendMessageForm
onSubmit={this.sendMessage}
onChange={this.sendTypingEvent}
/>
</section>
</div>
</div>
)
}
}
export default ChatScreen Das Verwalten des Zustands Ihrer Benutzer im React -Status kann etwas schwierig sein, daher verwalten wir ihn für Sie in currentRoom.users .
Wenn Benutzer eine Verbindung herstellen und sich trennen, wird diese Eigenschaft dynamisch aktualisiert. Mit anderen Worten, currentRoom.users sollten immer den aktuellen Status Ihrer Chat -App nachdenken.
Wenn Benutzer online kommen oder offline ( onPresenceChange ) oder neue Benutzer beitreten ( onUserAdded ), müssen wir nur Call forceUpdate tun, das React to Evaluse currentRoom.users und aktualisiert die Benutzeroberfläche.
Auch hier läuft es wirklich darauf hinaus, einige einfache Daten und Ereignisse zu verkabeln, um Komponenten zu reagieren, und das ist alles, Leute!
In dieser Vorgehensweise haben Sie eine komplette Chat -Anwendung mit erstellt
Da wir Chatkit verwendet haben, erhalten wir auch kostenlos einige Bonusfunktionen:
Wir haben eine ganze Menge Code geschrieben, aber nichts davon war besonders kompliziert.
Chatkit verfügt über eine minimale, aber leistungsstarke API, die alle unsere Chat -Daten für uns verwaltet. Alles, was wir tun mussten, ist diese Daten zu nehmen und sie für den Benutzer zu rendern.
Willst du weiter bauen? Fügen Sie nicht reichhaltige Medienunterstützung hinzu und lesen Sie Quittungen? Chatkit unterstützt beide:
Möglicherweise sind Sie auch daran interessiert, unsere leistungsstarke Chatkit Slack -Demo (250+ Sterne ️) zu überprüfen. Es ähnelt der Anwendung, die wir gerade erstellt haben, aber vollständiger.
Was wirst du mit Chatkit erstellen? Wir würden gerne sehen! Ihr Feedback führt uns bei der Verbesserung von Chatkit. Lassen Sie uns wissen, was Ihnen hilft, Ihre Ziele zu erreichen, was Ihnen in den Weg steht oder was fehlt.