https://d226lax1qjow5r.cloudfront.net/blog/blogposts/chat-app-with-react-and-nexmo-dr/React_Nexmo.png

Erstellen einer Chat-App mit React und Nexmo

Zuletzt aktualisiert am May 10, 2021

Lesedauer: 4 Minuten

Eine der einfachsten Möglichkeiten, online zu kommunizieren, ist auch eine der einfachsten, die Sie Ihrer Website hinzufügen können, indem Sie React und Nexmo's clientseitige JavaScript-Werkzeuge. Eine Chat-Anwendung kann Kundenservice bieten, die Zusammenarbeit an einem Projekt erleichtern oder Ihnen die Möglichkeit geben, sich mit Freunden auszutauschen. Und die gute Nachricht: Wenn Sie unser vorheriges Tutorial zu React und Express als Komplettlösungverfolgt haben, verfügen Sie bereits über die meisten Komponenten, die Sie zum Erstellen einer solchen Anwendung benötigen.

Voraussetzungen

Um es kurz zu machen, nehmen wir an, dass Sie haben gefolgt von dem React- und Express-Anleitung.

Wie im Full-Stack-Beispielcode wird der Beispielcode für dieses Tutorial die letztgenannte Anforderung durch die Verwendung von Glitch erfüllen.

Wenn Sie die Nexmo-Anwendung verwenden, die Sie für Ihre Full-Stack-Anwendung erstellt haben, können Sie eine oder zwei Conversation IDs generieren und diese in eine Textdatei kopieren, um sie im nächsten Schritt zu verwenden. Wenn Sie es vorziehen, eine neue Anwendung für dieses Projekt zu erstellen, können Sie die Konversationen über die Befehlszeile erstellen.

Vonage API-Konto

Um dieses Tutorial durchzuführen, benötigen Sie ein Vonage API-Konto. Wenn Sie noch keines haben, können Sie sich noch heute anmelden und mit einem kostenlosen Guthaben beginnen. Sobald Sie ein Konto haben, finden Sie Ihren API-Schlüssel und Ihr API-Geheimnis oben auf dem Vonage-API-Dashboard.

Hinzufügen von Chaträumen zu NexmoApp

Um die Funktionalität getrennt zu halten, fügen Sie eine neue Komponente zu Ihrer React-Anwendung unter client/src/Chatroom.js. Für den Moment können Sie sie weitgehend leer lassen:

import React from 'react';
import styles from './Chatroom.css';

class Chatroom extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  }
};

export default Chatroom;

Sie können auch eine CSS-Datei hinzufügen und diese in jeder Phase mit einem beliebigen Styling versehen.

Wenn Sie die Seite NexmoApp.js öffnen, sehen Sie eine Reihe von Verweisen auf die Conversation Komponente. Die Chatroom Komponente wird in ähnlicher Weise verwendet, also können Sie diese einfach durch Verweise auf Chatroom. Sie sollten sich in den imports und der render Funktion stehen.

Unter renderändern Sie das Chatroom Komponenten-Tag nur geringfügig, so dass Sie anstelle von inviteszu übergeben, übergeben Sie chats:

  render() {
    return (
      <div className="nexmo">
        <User onUpdate={this.userUpdated}/>
        <Chatroom app={this.state.app} loggedIn={!!this.state.token} chats={this.state.chats} />
      </div>
    );
  }

Die anderen Eigenschaften, die an Chatroom übergebenen Eigenschaften existieren bereits als Teil der Benutzerauthentifizierung und -anmeldung, aber chats ist derzeit nicht Teil des Zustands. Für diese einfache Anwendung codieren Sie die oben erstellten Konversationen fest in den Anfangszustand der Komponente. Sie können ihnen beliebige Namen geben, um sie für die Endbenutzer zu unterscheiden:

constructor(props) {
    super(props);
    this.state = {
      chats: [
        {
          id: 'CON-123e456c-5ff0-789c-8a11-e4a56a7b8c90',
          name: 'nice chat'
        },
        {
          id: 'CON-2c34ecec-f567-8e90-bf1d-23e4567e890a',
          name: 'serious business'
        }
      ]
    };
    
    this.login = this.login.bind(this);
    this.getJWT = this.getJWT.bind(this);
    this.userUpdated = this.userUpdated.bind(this);
  }

Da diese App keine Unterhaltungen oder Einladungen verwaltet, können Sie auch den Code in login um Konversationen zu erhalten. Damit bleibt diese Funktion nur noch für die Anmeldung und die Speicherung eines Verweises auf die Nexmo-Anwendung zuständig:

  login() {
    let nexmo = new nexmoClient();
    nexmo.createSession(this.state.token).then(app => {
      this.setState({
        app: app
      });
    });
  }

Ein einfacher Chatroom

Sie können den gesamten User Komponentencode in Ruhe lassen. Sie wird weiterhin das Gleiche tun, nämlich einen neuen Benutzer anlegen oder eine Liste der vorhandenen Benutzer anbieten. Sobald der Benutzer eingeloggt ist, kann er mit dem Chat fortfahren.

Die Komponente Chatroom Komponente enthält zwei Zustände: die Auswahl eines Chatraums und den Chatraum selbst. Hinter den Kulissen ist ein Chatraum nur eine Nexmo-Konversationalso wird ein Teil des Codes dieser Komponente ähnlich aussehen wie der Code der Conversation Komponente. Sie können die Funktionen und Bedingungen, die für beide Zustände benötigt werden, für den Anfang vorgeben:

import React from 'react';
import styles from './Chatroom.css';

class Chatroom extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      messages: []
    };
    
    this.joinConversation = this.joinConversation.bind(this);
    this.onMessage = this.onMessage.bind(this);
    this.setInput = this.setInput.bind(this);
    this.sendInput = this.sendInput.bind(this);
  }
  
  joinConversation(evt) {}
  
  onMessage(sender, message) {}
  
  setInput(evt) {}
  
  sendInput() {}
  
  render() {
    if (this.state.conversation) {
      
    } else {
     
    }
  }
};

export default Chatroom;

Einem Chat beitreten

Da dem Nutzer eine begrenzte Anzahl vordefinierter Chaträume zur Verfügung steht, kann er über ein Dropdown-Menü einfach einen auswählen. Hätten Sie nur einen einzigen Chat, könnten Sie auf diese Schnittstelle ganz verzichten. Um eine Auswahlliste für die beiden Chaträume zu erzeugen, die in NexmoAppkodiert sind, bilden Sie eine Schleife über das Array, um eine Reihe von options zu erstellen, dann fügen Sie sie als Kinder einer select:

  render() {
    if (this.state.conversation) {
    } else {
      let opts = [<option key="0">-</option>];
      this.props.chats.forEach(chat => {
        opts.push(<option key={chat.id} value={chat.id}>{chat.name}</option>);
      });
      
      return (
        <div className="conversation">
          <label>Choose a chat to join: 
            <select onChange={evt => this.joinConversation(evt)}>
              {opts}
            </select>
          </label>
        </div>
      );
    }
  }

Wenn sich der Wert der Auswahlliste ändert, joinConversation ausgelöst. Der joinConversation Handler holt sich die ausgewählte Konversation anhand ihrer ID aus der Nexmo-App und tritt ihr bei. Er speichert auch einen Verweis darauf und weist ihm einen anderen Event-Handler für eingehende Nachrichten zu:

  joinConversation(evt) {
    let select = evt.target;
    this.props.app.getConversation(select.value).then(conv => {
      conv.on('text', this.onMessage);
      conv.join();
      this.setState({
        conversation: conv
      });
    });
  }

Der onMessage Handler wird immer dann ausgelöst, wenn es ein neues text Ereignis in der aktiven Konversation gibt. Er erhält Informationen über das Gesprächsmitglied, das das Ereignis ausgelöst hat, und das Ereignisobjekt selbst. Für einen einfachen Chat können Sie die meisten dieser Informationen verwerfen und nur die ID, den Anzeigenamen des Benutzers und den Nachrichtentext speichern. Diese Informationen können mit einer Liste von Nachrichten verknüpft werden, die im Status gespeichert sind:

onMessage(sender, message) {
    let newMessages = this.state.messages.concat({
      key: message.id,
      sender: sender.display_name,
      text: message.body.text
    });
    this.setState({
      messages: newMessages
    });
  }

Wenn Sie auch nur einen einfachen Chat wie diesen für den produktiven Einsatz konzipieren würden, müssten Sie vorsehen, ältere Nachrichten nach einiger Zeit in ein anderes Speicherobjekt zu verschieben. Bei einer erheblichen Menge an Datenverkehr wird ein einziges Array für alle Nachrichten unweigerlich zu Problemen führen.

Versenden von Nachrichten

Sobald der Benutzer angemeldet ist und einem Chat beigetreten ist, wird er Nachrichten senden und empfangen wollen. Das bedeutet, dass Sie eine Benutzeroberfläche mit mindestens einem Bereich zum Anzeigen von Nachrichten und einem Eingabefeld für Text rendern möchten. Das JSX dafür füllt den anderen Zweig der Hauptbedingung in render. Es durchläuft Ihr Array von Nachrichten und rendert alles, was seit dem Eintritt des Benutzers in den Chat eingegangen ist. Darunter werden ein Textfeld und eine Schaltfläche bereitgestellt, die neu eingegebenen Text festlegen bzw. senden:

  render() {
    if (this.state.conversation) {
      let messagePane = [];
      
      if (this.state.messages.length) {
        this.state.messages.forEach(msg => {
          messagePane.push(<p key={msg.key} className="message"><b>{msg.sender}:</b>{msg.text}</p>);
        });
      }
      
      return (
        <div className="conversation">
          <div className="messages">
            {messagePane}
          </div>
          <div className="input">
            <textarea onBlur={evt => this.setInput(evt)} />
            <button onClick={evt => this.sendInput(evt)}>Chat</button>
          </div>
        </div>
      );
    } else {
      ...
    }
  }

Die durch den Nachrichteneingang ausgelösten Ereignisse werden in setInput und behandelt. sendInput. setInput speichert ganz einfach den eingegebenen Text im Zustand der Komponente:

  setInput(evt) {
    this.setState({
      input: evt.target.value
    });
  }

Der Button-Handler, sendInputnimmt den im Status gespeicherten Text und übergibt ihn an die Konversation mit sendText. Anschließend löscht er den Text im Status und in der davor liegenden Textarea:

 sendInput(evt) {
    this.state.conversation.sendText(this.state.input).then(() => {
      this.setState({
        input: null
      });
    });
    evt.target.previousSibling.value = '';
  }

Plaudern Sie drauf los!

Auch wenn die Fehlerbehandlung fehlt und die Leistung nicht beachtet wird, haben Sie jetzt eine sehr einfache Chat-Anwendung. Wenn man die Funktionen einer Produktionsanwendung entfernt, wird deutlich, wie wenig man braucht, um die wichtigsten Chat-Funktionen bereitzustellen:

  1. Ein Benutzer, der bei einer Nexmo-Anwendung angemeldet ist

  2. Eine Konversation für den Benutzer zum Mitmachen

  3. Ein Ereignisbehandler für empfangene Nachrichten

  4. Die Funktion sendText Funktion zur Aktivierung des Chattens

Ganz gleich, ob Sie einen Chatroom der alten Schule, eine Pop-up-Konversation zur Unterstützung verwirrter Kunden oder etwas anderes erstellen möchten, Sie können es mit diesen Elementen aufbauen. Sie müssen sich nicht um Sockets oder Polling kümmern. Und mit React müssen Sie nichts tun, um DOM-Aktualisierungen auszulösen. Jetzt können Sie sich auf Ihre Benutzeroberfläche und die Robustheit der Anwendung konzentrieren.

Teilen Sie:

https://a.storyblok.com/f/270183/250x250/f231d97f1b/garann-means.png
Garann MeansEntwickler Pädagoge

Ich bin ein JavaScript-Entwickler und ein Developer Educator bei Vonage. Im Laufe der Jahre habe ich mich für Templates, Node.js, progressive Web-Apps und Offline-First-Strategien begeistert, aber was ich immer geliebt habe, ist eine nützliche, gut dokumentierte API. Mein Ziel ist es, Ihre Erfahrung mit unseren APIs so gut wie möglich zu gestalten.