Ein Chat-Fenster mit React und Hooks erstellen
Published: 2024-03-07 07:45:04

**Bevor Sie weiterlesen...**Dieser Artikel aus unserem Archiv verwendet unser PubNub React SDK, aber neue Chat-Anwendungen sollten unser dediziertes, in TypeScript geschriebenes [Chat SDK](https://www.pubnub.com/docs/chat/chat-sdk/overview) und die dazugehörige [Beispiel-App](https://www.pubnub.com/docs/chat/chat-sdk/build/sample-chat) verwenden, die Hooks verwendet.

[Chat](https://pubnub.com/solutions/chat/) ist ein Schlüsselelement der meisten interaktiven Anwendungen. Von [einer App für das Gesundheitswesen](https://pubnub.com/solutions/digital-health/) über [Gruppenchats](https://www.pubnub.com/solutions/multiuser-collaboration/) bis hin zu Chatbots wird Echtzeitkommunikation von jeder Multi-User-App erwartet. Die Integration dieser Funktionalität ist viel einfacher, wenn Sie von Anfang an das richtige Framework und die richtige Infrastruktur wählen. In diesem Tutorial zeigen wir Ihnen, wie das geht: Wir erstellen ein Chat-Fenster mit [React](https://reactjs.org/), [Material-UI](https://material-ui.com/) und [PubNub](https://www.pubnub.com/).

Unsere App wird es jedem ermöglichen, sich zu verbinden und in Echtzeit auf jedem beliebigen Kanal zu chatten. Wir werden diesen Chat von Grund auf mit dem React-Framework und Material-UI-Komponenten erstellen. Die PubNub-API wird verwendet, um das Senden und Empfangen von Nachrichten abzuwickeln. Diese drei Komponenten werden uns helfen, einen modernen und schnellen Chat zu erstellen.

In diesem Tutorial verwenden wir auch [Hooks](https://reactjs.org/docs/hooks-intro.html), eine neue Art, React-Komponenten zu schreiben, die redundanten Code reduziert und zusammengehörige Teile organisiert. Warum und wie wir diese neuen Funktionen nutzen, erkläre ich im weiteren Verlauf des Tutorials. Nach diesem Tutorial werden wir einen Chat haben, der es jedem mit einem Kanalnamen ermöglicht, miteinander zu sprechen. Kanäle werden in der URL und auf der Seite dargestellt, so dass das Teilen von Kanälen einfach ist!

[![react hooks chat](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jkx/cadaa09d1dbce7a6f13e1fce08cc4a30/react-hooks-chat.gif)](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jkx/cadaa09d1dbce7a6f13e1fce08cc4a30/react-hooks-chat.gif)

Pub/Sub und Abrufen des Verlaufs
--------------------------------

PubNub bietet eine einfache und rasend schnelle Infrastruktur für den Versand von Nachrichten. PubNub wird verwendet, um praktisch unbegrenzte Mengen von Personen oder Systemen in weniger als einer Viertelsekunde weltweit zu verbinden. Mit den zahlreichen verfügbaren SDKs und dem [auf Chats ausgerichteten Ressourcenzentrum](https://www.pubnub.com/developers/chat-resource-center/) werdenIhre Anwendungsfälle abgedeckt . Bei der Erstellung dieser App werden wir Publish/Subscribe für Echtzeit-Nachrichten und Storage & Playback für die Speicherung von Nachrichten verwenden.

Das**Veröffentlichen** bietet uns die Möglichkeit, Nachrichten an diejenigen zu senden, die auf bestimmten Kanälen zuhören. Erfahren Sie, wie man [in React veröffentlicht](https://www.pubnub.com/docs/sdks/react#publish-and-subscribe).

Das**Abonnieren** ist die Art und Weise, wie wir PubNub mitteilen, dass wir Nachrichten empfangen möchten, die an bestimmte Kanäle gesendet werden. Lernen Sie , wie man[in React abonniert.](https://www.pubnub.com/docs/sdks/react#publish-and-subscribe)

**Storage & Playback** bedeutet, dass jemand im Moment nicht abonniert sein muss, um Nachrichten auf einem Kanal zu empfangen. Wenn ein Benutzer eine Verbindung herstellt, können wir die letzten Nachrichten abrufen, damit er sie sehen kann! Erfahren Sie, wie man [Nachrichten in React speichert und abspielt.](https://www.pubnub.com/docs/react-native-javascript/api-reference-storage-and-playback)

Erste Schritte
--------------

In diesem Chat-Beispiel müssen wir nur eine API für alle Chat-Funktionen verwenden. Sie müssen ein PubNub-Konto erstellen, indem Sie das unten eingebettete Formular verwenden, oder sich anmelden, wenn Sie bereits ein Konto haben.

Holen Sie sich zunächst Ihre eindeutigen Pub/Sub-Schlüssel im [Admin-Dashboard und](https://admin.pubnub.com/) aktivieren Sie dann unten links auf der Seite mit den Schlüsseloptionen die Option Speicherung und Wiedergabe. Ich habe die Aufbewahrungszeit für meine Nachrichten auf einen Tag eingestellt, aber Sie können auch einen anderen Zeitrahmen wählen, der für Sie am besten geeignet ist. Achten Sie darauf, Ihre Änderungen zu speichern.

Jetzt können wir mit dem Einrichten unseres React-Projekts beginnen.

### So installieren Sie React.js und PubNub

Um React.js und PubNub zu installieren, müssen wir zunächst sicherstellen, dass wir Node.js und npm haben. Installieren Sie diese auf der [offiziellen Node.js-Homepage](https://nodejs.org/en/). Wenn Sie sie bereits installiert haben, stellen Sie sicher, dass Ihre npm-Version über 5.2 liegt, indem Sie

```js
npm -v
```

in Ihr Terminal eingeben. Jetzt haben wir unsere Paketmanager, um unsere React-App zu erstellen und unser PubNub-SDK zu installieren.

Sobald Sie Node.js installiert haben, führen Sie diese Befehle aus, um Ihr Projekt zu erstellen und die notwendigen Module zu installieren. Warten Sie, bis React Ihre Website erstellt hat! Sobald das erledigt ist, wird die zweite Zeile PubNub installieren. Mit der dritten Zeile wird unser Styling-Framework Material-UI installiert.

```js
npx create-react-app <your-app-name>
cd <your-app-name>
npm install --save pubnub
npm install @material-ui/core
```

Jetzt haben wir alles, was wir brauchen, um mit dem Programmieren zu beginnen! Wenn du

```js
npm start
```

in dein Terminal eingibst und auf den Link klickst, solltest du nach dem Start eine leere React-Seite sehen! Lasst uns mit dem Programmieren beginnen!

Warum React Hooks verwenden?
----------------------------

Vor Oktober 2018 musste man [Klassenkomponenten](https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class)verwenden [, um lokale Variablen zu speichern](https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class). Hooks haben uns die Möglichkeit gegeben, Zustände innerhalb von funktionalen Komponenten zu speichern, und Hooks haben einen Großteil des Aufwands entfernt, der mit Klassen einhergeht.

Hooks erleichtern die Entwicklung umfangreicher Anwendungen, denn ihre Funktionen helfen uns, ähnlichen Code zu gruppieren. Wir organisieren die Logik in unseren Komponenten danach, was sie tun, und nicht danach, wann sie es tun müssen. Wir verzichten auf die üblichen Lebenszyklusfunktionen wie componentDidMountundcomponentDidUpdate und verwenden stattdessen useEffect.

useEffect ist einer der beiden Haupt-Hooks, die wir verwenden, der andere ist useState. useState ist das neue setState, funktioniert aber ein wenig anders. Die [React Hooks-Dokumentation](https://reactjs.org/docs/hooks-intro.html) geht auf einige weitere Details ein, aber ein weiterer großartiger Teil über Hooks ist, dass wir unsere eigenen erstellen können! Das spart Zeit und Codezeilen, da wir das nutzen können, was wir bereits getan haben.

In diesem Tutorial zeige ich Ihnen, wie Sie useEffect und useState verwenden und Ihren eigenen Hook erstellen können!

Einen eigenen React-Hook erstellen
----------------------------------

Beginnen wir damit, unseren eigenen Hook zu erstellen, der uns in Zukunft einiges an Code vereinfacht. Anstatt onChange-Funktionen für jeden Input einzeln zu erstellen, bündeln wir jetzt alles, was wir für jeden Input tun können, in einem Hook!

Wenn Sie einen Blick in den Projektordner werfen, den wir erstellt haben, können Sie sehen, dass wir einige verschiedene Ordner haben. Navigieren Sie in den Ordner "src" und erstellen Sie dort eine neue Datei namens "useInput.js". Die Regeln für Hooks besagen, dass alle Hooks mit "use" beginnen müssen. Sie besagen auch, dass Hooks nur auf der obersten Ebene verwendet werden sollten, d. h. wir können sie nicht in Funktionen, Bedingungen oder Schleifen verwenden. Wir können sie auch nicht von regulären JS-Funktionen aus aufrufen, sondern nur von React-Funktionskomponenten und benutzerdefinierten Hooks! Nun, da wir die allgemeinen Regeln kennen, können wir einen erstellen!

Durch diesen Hook werden wir den useState Hook verwenden. Importieren Sie useState aus 'react' am Anfang Ihrer Datei und erstellen Sie eine Funktion mit dem Namen 'useInput', Sie haben es erraten.

```js
import { useState } from 'react';
function useInput()
{
  //Define our Hook
}
```

An dieser Stelle können wir mit unserer Syntax ein wenig verrücktspielen. Wir können eine Destrukturierungszuweisung verwenden, um die beiden Objekte zu erhalten, die uns useState liefert, und brauchen dafür nur eine Zeile Code. Aber was liefert uns useState? Im Grunde gibt es einen Getter und einen Setter zurück, eine Variable, die den Wert enthält, und eine Funktion, um ihn zu setzen! Anstelle des Zugriffs auf unseren Status über

```js
this.state.xxxxx
```

zuzugreifen, können wir ihn allein über den Namen aufrufen.

```js
let [value, setValue] = useState('');
```

Erstellen Sie einen Funktionsausdruck, der einer neuen Variablen namens onChange zugewiesen wird. Wir übergeben "event" an die Funktion und setzen darin unseren Statuswert auf den Wert des Ziels des Ereignisses. Danach geben wir die drei Variablen/Funktionen zurück, die wir erstellt haben: value, setValue und onChange.

```js
let onChange = function(event){
  setValue(event.target.value);
};
return {
  value,
  setValue,
  onChange
};
```

Schließlich

```js
export default useInput;
```

am Ende unserer Datei, um sie für unsere Haupt-App zur Verfügung zu stellen!

Entwerfen unserer React-Komponenten
-----------------------------------

Jetzt, wo wir unseren Hook fertiggestellt haben. Richten wir nun unsere App.js-Datei ein! Am Anfang unserer Datei müssen wir ein paar wichtige Dateien importieren: React und die beiden Standard-Hooks, die wir benötigen, unseren useInput-Hook, den wir gerade erstellt haben, unsere App.css-Datei, PubNub und die Material-UI-Komponenten.

Ersetzen Sie den Inhalt Ihrer App.css durch den folgenden Text.

```js
* {
  margin: 0;
  padding: 0;
}
body {
  width: 500px;
  margin: 30px auto;
  background-color: #fff;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
    "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
    monospace;
}
.top {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
}
```

Lassen Sie uns einen Umriss unseres Chats mit Hilfe unserer funktionalen Komponenten-Header erstellen. Dies wird uns helfen herauszufinden, welche Art von Design und Fluss wir für unseren Chat wollen. Ich habe drei verschiedene Komponenten gewählt: App, Log und Nachricht.

App enthält das Protokoll, die Eingaben und die Schaltfläche "Senden". Log enthält eine Liste von Nachrichten, und Message zeigt die Nachricht und den Absender an. Achten Sie darauf, dass Sie die erforderlichen Module am Anfang Ihrer Datei importieren!

```js
//These are the two hooks we use the most of through this Chat
import React, { useState, useEffect} from 'react';
//has a few css stylings that we need.
import './App.css';
//This is a hook we created to reduce some of the bloat we get with watching inputs for changes.
import useInput from './useInput.js';
//Lets us import PubNub for our chat infrastructure capabailites.
import PubNub from 'pubnub';
//Material UI Components
import {Card, CardActions, CardContent,List, ListItem,Button,Typography,Input} from '@material-ui/core';
// Our main Component, the parent to all the others, the one to rule them all.
function App(){
  //Bunch of functions!
  //return()
}
//Log functional component that contains the list of messages
function Log(props){
  //return()
}
//Our message functional component that formats each message.
function Message(props){
  //return()
}
```

Jede dieser Komponenten enthält eine Rückgabefunktion, mit der wir gestalten können, wie sie aussehen soll. Wir können bestimmen, welche Informationen wir von unseren Eltern an unsere Kinder weitergeben. Auf diese Weise geben wir nur Informationen nach unten weiter und geben jeder Komponente das, was sie zum Funktionieren braucht.

App-Komponente einrichten: Zustand mit React Hooks
--------------------------------------------------

Unsere App ist unsere wichtigste React-Chat-Komponente. Für diese Komponente müssen wir ein paar Dinge einrichten, wie z.B. die Überprüfung der URL auf Änderungen am Kanal, die Einrichtung unserer Zustände, dann können wir ein paar useEffect-Funktionen erstellen, um zu sortieren, was die App tun soll und wann das alles passiert.

Die erste Aktion innerhalb unserer App besteht darin, einen Standardkanal zu erstellen. "Global" ist eine gute Wahl. Dann prüfen wir die URL auf einen Kanal. Wenn es keinen gibt, können wir den Standardkanal so lassen, wie er ist, aber wenn es einen gibt, dann setzen wir den Standardkanal auf diesen.

```js
let defaultChannel = "Global";
//Access the parameters provided in the URL
let query = window.location.search.substring(1);
let params = query.split("&");
for(let i = 0; i < params.length;i++){
  var pair = params[i].split("=");
  //If the user input a channel then the default channel is now set
  //If not, we still navigate to the default channel.
  if(pair[0] === "channel" && pair[1] !== ""){
    defaultChannel = pair[1];
  }
}
```

Definieren wir nun unsere Zustände mit ihren Anfangswerten. Verwenden Sie useState, um Getter und Setter für unseren Kanal zu erhalten, und stellen Sie sicher, dass Sie unseren Standardkanal als Anfangswert setzen. Machen Sie dasselbe für unser messages-Array, aber initialisieren Sie es mit einem leeren Array.

Ich setze auch einen generischen Benutzernamen für den Benutzer, basierend auf der aktuellen Zeit. Als Nächstes setzen Sie eine temporäre Kanal- und Nachrichtenvariable auf den neuen Hook, den wir erstellt haben. Das war's, wir haben unsere Zustände für unsere App eingerichtet.

```js
const [channel,setChannel] = useState(defaultChannel);
const [messages,setMessages] = useState([]);
const [username,] = useState(['user', new Date().getTime()].join('-'));
const tempChannel = useInput();
const tempMessage = useInput();
```

useEffect in React
------------------

Als nächstes verwenden wir den schicken neuen useEffect, über den alle reden. Dies ersetzt und reorganisiert im Grunde alle alten Lifecycle-Methoden, wenn wir keine Hooks verwenden. Jede Funktion wird bei jedem Rerender ausgeführt, es sei denn, wir geben ein Array von Variablen als zweiten Parameter an, dem sie folgen soll. Jedes Mal, wenn sich diese Variablen ändern, wird die useEffect-Funktion erneut ausgeführt.

_Denken Sie daran: Dies ist eine SHALLOW-Gleichheitsprüfung. Zahlen und Zeichenketten gelten jedes Mal als unterschiedlich, wenn Sie sie als etwas anderes setzen, aber useEffect betrachtet nur die Zeiger von Objekten, nicht ihre Attribute._

Wir können mehrere dieser Funktionen haben, nur muss jeder ihrer zweiten Parameter unterschiedlich sein. Im Wesentlichen wird jeder useEffect danach gruppiert, wovon er abhängt, um sich zu ändern, so dass Aktionen mit ähnlichen Abhängigkeiten zusammen laufen.

```js
useEffect(()=>{
  //Put code we want to run every time these next variables/states change
},[channel, username]);
```

Einrichten von PubNub in React
------------------------------

Jetzt, wo wir wissen, wie dieser neue Hook funktioniert, ist der nächste Schritt, ein neues PubNub-Objekt zu erstellen! Rufen Sie PubNub auf, um die zuvor generierten Veröffentlichungs- und Abo-Schlüssel zu holen und sie in Ihr neues Objekt zu übertragen. Sie können auch [eine UUID](https://www.pubnub.com/docs/react-native-javascript/api-reference-configuration#uuid) für diese Verbindung [festlegen](https://www.pubnub.com/docs/react-native-javascript/api-reference-configuration#uuid), sei es eine IP, ein Benutzername, eine [generierte UUID](https://www.pubnub.com/docs/react-native-javascript/api-reference-configuration#generate-uuid-arg) oder ein beliebiger eindeutiger Bezeichner, den Ihr Anwendungsfall definiert. Ich habe der Einfachheit halber den Benutzernamen festgelegt.

```js
const pubnub = new PubNub({
  publishKey: "<ENTER-PUB-KEY-HERE>",
  subscribeKey: "<ENTER-SUB-KEY-HERE>",
  uuid: username
});
```

Nachdem wir unser Objekt mit unseren Verbindungsinformationen gefüllt haben, fügen wir einen [Listener für PubNub-Ereignisse](https://www.pubnub.com/docs/web-javascript/api-reference-publish-and-subscribe#listeners)ein ! Dies ist nützlich, um neue Nachrichten, neue Verbindungen oder Status zu erkennen und auch um Präsenzereignisse zu verarbeiten. Unsere App verwendet weder Presence noch ist es notwendig, auch einen Status-Listener zu erstellen, aber ich möchte zumindest den Status implementieren und einige Ergebnisse protokollieren. Was wir für unsere Anwendung wirklich brauchen, ist die Fähigkeit, eingehende Nachrichten zu empfangen und zu verarbeiten, also lasst uns das definieren!

Prüfen Sie, ob der Nachrichtentext null oder leer ist, und wenn nicht, erstellen Sie ein newMessage-Objekt. Legen Sie das messages-Array als aktuellen Zustand fest, der mit der neuen Nachricht, die wir erhalten, verkettet wird. Die Pfeilfunktion stellt sicher, dass wir den aktuellen Zustand der Nachrichten verwenden und nicht den Zustand des ursprünglichen Renderings.

```js
pubnub.addListener({
  status: function(statusEvent) {
    if (statusEvent.category === "PNConnectedCategory") {
      console.log("Connected to PubNub!")
    }
  },
  message: function(msg) {
    if(msg.message.text){
      let newMessages = [];
      newMessages.push({
        uuid:msg.message.uuid,
        text: msg.message.text
      });
      setMessages(messages=>messages.concat(newMessages))
    }
  }
});
```

Das Abonnieren des Kanals in unserem Zustand wird unsere erste Verbindung zum PubNub-Server sein! Wenn Presence für Ihren Anwendungsfall wichtig ist, können Sie es hier aktivieren. Finden Sie heraus, wer sich in einem Channel mit [Presence auf dem PubNub React SDK](https://www.pubnub.com/docs/react-native-javascript/api-reference-presence)befindet .

```js
pubnub.subscribe({
  channels: [channel]
});
```

Die Einbeziehung des Verlaufs ist eine Schlüsselfunktion jedes Chats, also lassen Sie uns ein paar Nachrichten ziehen, um ein Chatprotokoll zu erstellen. Wenn wir uns zum ersten Mal mit einem Kanal verbinden, verwenden wir die History-Funktion, um die gespeicherten Nachrichten abzurufen. Verwenden Sie die Antwort, um auf die alten Nachrichten zuzugreifen und sie in einem temporären Array zu speichern. Da unser Array leer sein sollte, können wir diese alten Nachrichten in unser leeres Nachrichten-Array verschieben.

```js
pubnub.history({
      channel: channel,
      count: 10, // 100 is the default
      stringifiedTimeToken: true // false is the default
}, function (status, response){
  let newMessages = [];
  for (let i  = 0; i < response.messages.length;i++){
    newMessages.push({
      uuid:response.messages[i].entry.uuid ,
      text: response.messages[i].entry.text
    });
  }
  setMessages(messages=>messages.concat(newMessages))
});
```

Ein weiterer großartiger Teil von useEffect ist, dass wir ein Verhalten definieren können, das alles beendet, bevor es wieder läuft! Wir geben eine Funktion "cleanup" zurück, [melden uns von allen Kanälen ab](https://pubnub.com/developers/chat-resource-center/docs/reference/connecting#disconnecting-from-pubnub) und setzen die Nachrichten in ein anderes leeres Array.

```js
return function cleanup(){
  pubnub.unsubscribeAll();
  setMessages([]);
}
```

Pub/Sub: Veröffentlichen
------------------------

Wir haben einen Kanal abonniert, aber wir haben noch nicht veröffentlicht. Im Gegensatz zu den PubNub-Funktionen im vorherigen useEffect wollen wir veröffentlichen, wenn der Benutzer eine Nachricht sendet. Erstellen wir eine Funktion mit dem Namen publishMessage, die Nachrichten in unserem Kanal veröffentlichen wird.

Erstellen Sie die Funktion und prüfen Sie, ob in unserer temporären Nachricht etwas enthalten ist. Wenn ja, erstellen Sie Ihr Nachrichtenobjekt! Ich habe sowohl die Nachricht als auch den Benutzernamen hinzugefügt, damit wir wissen, wer sie gesendet hat, wenn wir von einem beliebigen Gerät aus auf die Nachrichten zugreifen. Beginnen Sie mit der Erstellung eines weiteren PubNub-Objekts, das genau so aussieht wie das letzte. Rufen Sie publish auf und geben Sie dabei unsere neue Nachricht und den Kanal als Argument an.

Nachdem wir die Nachricht gesendet haben, löschen wir unseren temporären Nachrichtenstatus. So kann der Benutzer eine weitere Nachricht senden, wenn er möchte. Jetzt haben wir noch keinen Code, der diese Funktion aufruft, also wird sie nicht ausgelöst, aber die nächste Funktion, die wir definieren, wird es!

```js
function publishMessage(){
  if (tempMessage.value) {
    let messageObject = {
      text: tempMessage.value,
      uuid: username
    };
    const pubnub = new PubNub({
      publishKey: "<ENTER-PUB-KEY-HERE>",
      subscribeKey: "<ENTER-SUB-KEY-HERE>",
      uuid: username
    });
    pubnub.publish({
      message: messageObject,
      channel: channel
    });
    tempMessage.setValue('');
  }
}
```

React Event Handler erstellen
-----------------------------

Es ist wichtig, dass wir flüssige Benutzerinteraktionen mit unserem Chat erstellen. Lassen Sie uns einen Handler für Benutzer erstellen, die entweder eine Nachricht abschicken oder den Kanal über die Eingabetaste wechseln. Wir werden eine Funktion erstellen, die ich handleKeyDown nenne und die ein Ereignisobjekt annimmt.

```js
function handleKeyDown(event){
  //Handling key down event
}
```

Sobald wir uns in dieser Funktion befinden, ist es unser Ziel, herauszufinden, was dieses Ereignis auslöst. Später, wenn wir die Eingänge erstellen, werden wir IDs für sie festlegen. Beginnen Sie mit der Überprüfung der ID des Ziels des Ereignisses. Wenn es "messageInput" ist, prüfen Sie, ob die gedrückte Taste "Enter" war oder nicht. Wenn ja, rufen Sie unsere Funktion publishMessage auf.

```js
if(event.target.id === "messageInput"){
  if (event.key === 'Enter') {
    publishMessage();
  }
}
```

Führen Sie die gleichen Überprüfungen durch, um diese else if-Anweisung zu starten wie die vorherige, aber verwenden Sie dieses Mal "channelInput" als ID. Erstellen Sie einen konstanten Wert, der unseren temporären Kanal enthält, aber stellen Sie sicher, dass Sie alle führenden oder nachgestellten Leerzeichen entfernen. Würden wir hier nur setChannel aufrufen, bräuchten wir nicht zu prüfen, ob der neue und der alte Kanal identisch sind.

Da wir aber auch die aktuelle URL in die von uns erstellte ändern, brauchen wir die Prüfung, da es sonst zu unnötigen Duplikaten kommen würde. Die Erstellung einer neuen URL-Zeichenfolge, die den neuen Kanalnamen enthält, ermöglicht es den Benutzern außerdem, Seitenlinks leichter weiterzugeben. Schließlich setzen wir den Status unseres temporären Channels auf eine leere Zeichenfolge.

```js
else if(event.target.id === "channelInput"){
  if (event.key === 'Enter') {
    //Navigates to new channels
    const newChannel = tempChannel.value.trim()
    if(newChannel){
      if(channel !== newChannel){
        //If the user isnt trying to navigate to the same channel theyre on
        setChannel(newChannel);
        let newURL = window.location.origin + "?channel=" + newChannel;
        window.history.pushState(null, '',newURL);
        tempChannel.setValue('');
      }
    }
  //What if there was nothing in newChannel?
}
```

Das ist großartig, wenn der Benutzer einen Kanal in unsere Eingabe eingibt, aber was ist, wenn er es nicht tut? Dann können wir sie entweder auf ihren Fehler hinweisen, im selben Kanal bleiben oder sie zu einem Standardkanal unserer Wahl bringen. Ich habe mich für die letzte Option entschieden, d. h. für die Option "Global". Führen Sie die gleiche Prüfung wie zuvor durch, aber verwenden Sie diesmal "Global" und legen Sie den Kanal als solchen fest.

Wir erstellen eine neue URL und übertragen sie wie zuvor in unseren Seitenverlauf, jedoch ohne Parameter. Der Code, den wir am Anfang unserer App eingefügt haben, wird dies erkennen und den Standardkanal verwenden. Auch hier setzen wir den temporären Kanal auf eine leere Zeichenkette und stellen sicher, dass wir diesen Codeschnipsel vor der letzten geschweiften Klammer einfügen.

```js
else{
  //If the user didnt put anything into the channel Input
  if(channel !== "Global"){
    //If the user isnt trying to navigate to the same channel theyre on
    setChannel("Global");
    let newURL = window.location.origin;
    window.history.pushState(null, '',newURL);
    tempChannel.setValue('');
  }
}
```

Wir fügen die aktuelle URL in den Verlauf der Zurück-Schaltfläche unseres Browsers ein, um unseren Nutzern die Möglichkeit zu geben, dadurch zu früheren Kanälen zu navigieren. Damit unser Chat tatsächlich mit der Zurück-Schaltfläche zwischen vorherigen Kanälen hin- und herwechseln kann, müssen wir noch ein paar Dinge tun.

Zwischen vorherigen Kanälen navigieren
--------------------------------------

Nachdem wir nun alle Funktionen für unseren React-Chatroom eingerichtet haben, fügen wir eine Funktion hinzu, um unsere Seite neu zu rendern. Wir werden unseren Status ändern, anstatt neu zu laden, wenn ein Benutzer zwischen unseren Seiten zurück oder vor klickt.

Erstellen Sie eine Funktion mit dem Namen goBack, die die URL eines Kanals prüft und entweder "Global" oder den gefundenen Kanal für unseren Kanalstatus setzt. Diese Funktion wird nur dann ausgeführt, wenn wir unserer Seite Ereignis-Listener hinzufügen!

```js
function goBack() {
  //Access the parameters provided in the URL
  let query = window.location.search.substring(1);
  if(!query){
    setChannel("Global")
  }else{
    let params = query.split("&");
    for(let i = 0; i < params.length;i++){
      var pair = params[i].split("=");
      //If the user input a channel then the default channel is now set
      //If not, we still navigate to the default channel.
      if(pair[0] === "channel" && pair[1] !== ""){
          setChannel(pair[1])
      }
    }
  }
}
```

Wir wollen den Listener nur hinzufügen, wenn die Seite geladen wird, und ihn entfernen, wenn wir sie verlassen. Das klingt nach einer weiteren Verwendung für einen useEffect-Hook! Erstellen Sie einen weiteren, aber geben Sie ein leeres Array als zweites Argument an. Dies wird nur einmal beim ersten Laden unseres Chats ausgeführt. Es wird nicht bei jeder erneuten Darstellung ausgeführt.

Erstellen Sie einen Ereignis-Listener für unser "Fenster" und geben Sie eine Cleanup-Funktion zurück, die diesen Listener entfernt. Der Ereignis-Listener wartet auf "popstate", d.h. wenn der Benutzer auf die Schaltfläche "Zurück/Vorwärts" in seinem Browser klickt. Setzen Sie die letzte Funktion, die wir erstellt haben, "goBack", hinter den Ereignisnamen. Jetzt wird unsere Seite nicht mehr neu geladen, sondern sie gibt das wieder, was sie braucht, wenn sie es braucht!

```js
useEffect(() => {
  window.addEventListener("popstate",goBack);
  return function cleanup(){
    window.removeEventListener("popstate",goBack);
  }
},[]);
```

Verwendung von JSX zur Erstellung einer React UI
------------------------------------------------

Nun, da wir die gesamte Logik in unserem Backend fertiggestellt haben, wollen wir ein einfaches, aber modernes Frontend erstellen! Dazu verwenden wir[JSX](https://reactjs.org/docs/introducing-jsx.html), eine JavaScript-UI-Beschreibungssprache. Sie ermöglicht uns die Verwendung eigener Variablen und Objekte innerhalb von Gruppen, die Komponenten genannt werden. Die Syntax sieht ähnlich aus wie HTML mit einer Templating-Engine, aber es ist JSX!

Wenn sich eine Variable/ein Zustand ändert, wird jede Komponente, die sie verwendet, mit dem neuen Wert neu gerendert. Das macht unsere App reaktionsschneller, denn sobald sich eine Änderung ergibt, wird sie aktualisiert. Aus diesem Grund ist es eine großartige Idee, PubNub und React zusammen zu verwenden. PubNub ist in der Lage, Nachrichten schnell zu liefern, und React hält mit, indem es seine Komponenten aktualisiert!

### App-Entwurf

Lassen Sie uns nun das Design für unsere App-Komponente entwerfen. Material-UI stellt uns schöne Komponenten zur Verfügung, die wir verwenden und mit unseren eigenen Informationen füllen können. Verwenden Sie das folgende Design und wir werden uns ansehen, welche Funktionen in bestimmten Bereichen aufgerufen werden.

```js
return(
  <Card >
    <CardContent>
      <div className="top">
        <Typography variant="h4" inline >
          PubNub React Chat
          </Typography>
        <Input
          style={{width:'100px'}}
          className="channel"
          id="channelInput"
          onKeyDown={handleKeyDown}
          placeholder ={channel}
          onChange = {tempChannel.onChange}
          value={tempChannel.value}
        />
      </div>
      <div >
        <Log messages={messages}/>
      </div>
    </CardContent>
    <CardActions>
      <Input
        placeholder="Enter a message"
        fullWidth={true}
        id="messageInput"
        value={tempMessage.value}
        onChange={tempMessage.onChange}
        onKeyDown={handleKeyDown}
        inputProps={{'aria-label': 'Message Field',}}
        autoFocus={true}
      />
      <Button
        size="small"
        color="primary"
        onClick={publishMessage}
        >
        Submit
      </Button>
    </CardActions>
  </Card>
);
```

Es sieht vielleicht nach einer Menge Design aus, aber es ist die Organisation von ein paar verschiedenen Elementen.

Zuerst haben wir unseren Titel innerhalb einer Typografie-Komponente. Danach befindet sich im selben Div unser Kanal Input. Inputs enthalten viele Eigenschaften, die die Aktionen definieren, die sie ausführen können. Dazu gehören seine ID, die Funktion, die onKeyDown behandelt, sein Platzhalter, die onChange-Funktion und sein Wert.

Es gibt auch Bereiche, in denen die Stile referenziert werden können. Nach diesem Div folgt unser Log, eine weitere funktionale Komponente, die wir noch nicht erstellt haben. Dieses Log nimmt unser messages-Array auf und wird jedes Mal neu gerendert, wenn sich dieses Array ändert. Nach unserem Log können wir eine weitere Eingabe und eine Schaltfläche einfügen. Die Eingabe ist der Ort, an dem der Benutzer eine Nachricht erstellt. Wir füllen seine Eigenschaften mit den jeweiligen Zuständen und Variablen, die es betrifft.

Wir stellen auch den Autofokus ein. Setzen Sie den onClick des Buttons auf unsere Funktion zum Veröffentlichen von Nachrichten, damit die Benutzer eine weitere Möglichkeit haben, ihre Nachrichten zu senden. Dies ist das Ende unserer App-Komponente und das Back-End ist fertig. Als nächstes müssen wir zwei weitere kleine Komponenten erstellen, um unsere Nachrichten anzuzeigen.

### Log- und Nachrichtendesign

Unsere App definiert einen Großteil der Funktionsweise unseres Chats, aber wir benötigen zwei weitere Komponenten, um sie zu vervollständigen. Beide geben JSX zurück und organisieren, wie unsere Nachrichten angezeigt werden. Die erste Komponente, Log, zeigt eine Liste von mit Typografie gefüllten ListItems an. Diese ListItems iterieren durch eine Karte unserer Nachrichten und geben eine Nachricht aus. Wir erstellen Message mit dem Schlüssel des Index im Array, der uuid der Nachricht und dem Text der Nachricht.

```js
function Log(props) {
  return(
    <List component="nav">
      <ListItem>
      <Typography component="div">
        { props.messages.map((item, index)=>(
          <Message key={index} uuid={item.uuid} text={item.text}/>
        )) }
      </Typography>
      </ListItem>
    </List>
  )
};
```

Die Komponente Message stellt eine einzelne Nachricht dar, ein div-Element, das mit der uuid und dem Text gefüllt und durch einen Doppelpunkt getrennt ist. Die Kinder unserer App-Komponente greifen über Requisiten auf die Nachrichten zu. Sie können nicht bearbeiten oder ändern, sondern nur lesen und anzeigen, was ihnen übergeben wird.

Nachdem wir nun die Definition unserer Komponenten abgeschlossen haben, beenden wir unsere App, indem wir sie am Ende der Datei exportieren. Der Code in index.js wird unsere App auf der Webseite darstellen!Führen Sie

```js
npm start
```

in unserem Projektordner aus und navigieren Sie zu [localhost:3000](localhost:3000) in unserem Browser, um zu sehen, dass unsere App läuft!

```js
function Message(props){
  return (
    <div >
      { props.uuid }: { props.text }
    </div>
  );
}
export default App;
```

Hier ist ein Gif des Chats in Aktion:

[![react hooks chat gif](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jkx/cadaa09d1dbce7a6f13e1fce08cc4a30/react-hooks-chat.gif)](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jkx/cadaa09d1dbce7a6f13e1fce08cc4a30/react-hooks-chat.gif)

Wir haben erfolgreich eine App entwickelt, mit der Benutzer in Kanälen ihrer Wahl chatten können. Das vollständige [Code-Repository finden Sie auch hier](https://github.com/PubNubDevelopers/ReactHooksChat.PubNub).

Wie geht's weiter?
------------------

Jetzt, wo Sie Ihre grundlegende Messaging-Funktionalität implementiert haben, ist es an der Zeit, weitere Funktionen hinzuzufügen! Besuchen Sie unsere [Seite mit den Chat-Lösungen](https://www.pubnub.com/solutions/chat/), um neue Tutorials, Best Practices und Design Patterns zu entdecken, mit denen Sie Ihre Chat-App auf die nächste Stufe heben können.

  
**Wenn der eingebettete Inhalt** auf dieser Seite **nicht verfügbar ist**, kann er auch unter [https://pubsub-quickstart-app.pubnub.com/signup](https://pubsub-quickstart-app.pubnub.com/signup) angesehen werden.

#### Inhalt

[Pub/Sub und das Abrufen des](#h-0)[VerlaufsEinstiegWie](#h-1)[man React.js und PubNub installiertWarum](#h-2)[React Hooks verwenden?](#h-3)[Erstellen Sie einen benutzerdefinierten React HookDesignen Sie](#h-4)[unsere React-KomponentenEinrichten](#h-5)[der App-Komponente: State mit React HooksEffect](#h-6)[in React](#h-7)[verwendenPubNub in React einrichtenPub/Sub](#h-8)[: PublizierenErstellen von](#h-9)[React Event HandlernNavigieren](#h-10)[zwischen vorherigen](#h-11)[ChannelsJSX](#h-12)[verwenden](#h-11)[, um ein React UIApp](#h-12)[DesignLog](#h-13)[und Message DesignWas](#h-14)[kommt als nächstes?](#h-15)

Wie kann PubNub Ihnen helfen?
=============================

Dieser Artikel wurde ursprünglich auf [PubNub.com](https://www.pubnub.com/blog/creating-a-chat-window-using-react-and-hooks/) veröffentlicht.

Unsere Plattform unterstützt Entwickler bei der Erstellung, Bereitstellung und Verwaltung von Echtzeit-Interaktivität für Webanwendungen, mobile Anwendungen und IoT-Geräte.

Die Grundlage unserer Plattform ist das größte und am besten skalierbare Echtzeit-Edge-Messaging-Netzwerk der Branche. Mit über 15 Points-of-Presence weltweit, die 800 Millionen monatlich aktive Nutzer unterstützen, und einer Zuverlässigkeit von 99,999 % müssen Sie sich keine Sorgen über Ausfälle, Gleichzeitigkeitsgrenzen oder Latenzprobleme aufgrund von Verkehrsspitzen machen.

PubNub erleben
--------------

Sehen Sie sich die [Live Tour](https://www.pubnub.com/tour/introduction/) an, um in weniger als 5 Minuten die grundlegenden Konzepte hinter jeder PubNub-gestützten App zu verstehen

Einrichten
----------

Melden Sie sich für einen [PubNub-Account](https://admin.pubnub.com/signup/) an und erhalten Sie sofort kostenlosen Zugang zu den PubNub-Schlüsseln

Beginnen Sie
------------

Mit den [PubNub-Dokumenten](https://www.pubnub.com/docs) können Sie sofort loslegen, unabhängig von Ihrem Anwendungsfall oder [SDK](https://www.pubnub.com/docs)