Erstellung einer einfachen Benutzeroberfläche mit ReactJS

0 Aktien
0
0
0
0

Einführung

Wir entwickeln eine einfache Chat-Anwendung mit ReactJS auf Basis des bereits implementierten Servers. Zunächst erstellen wir statische Komponenten, die anschließend mit dem Zustand verknüpft werden. Im letzten Schritt abonnieren wir den Ereignisserver.

Voraussetzungen
  • Grundkenntnisse in JavaScript und ReactJS (ich versuche, es einfach zu halten).
  • npm v6
  • npx v6
  • Node v12

Schritt 1: Projekt starten

Führen Sie in Ihrem Projektordner den Befehl `npx create-react-app --use-npm simple-chat-app` aus und warten Sie, bis die Installation abgeschlossen ist. Dadurch werden alle notwendigen Abhängigkeiten hinzugefügt und eine einfache Entwicklung und ein unkomplizierter Build-Prozess ermöglicht.

Fügen Sie die folgenden Dateien zum src-Ordner hinzu:

  • App.js (sollte bereits existieren)
  • ChatLineHolder.js
  • ChatLine.js
  • ChatInput.js

Führen Sie im Projektordner in Ihrer Konsole den Befehl `npm run start` aus. Dadurch wird ein Entwicklungsserver gestartet und die Anwendung in Ihrem Standardbrowser geöffnet.

Im src-Ordner sollte bereits eine App.js-Datei vorhanden sein. Sie können vorerst alle von ihr zurückgegebenen Informationen löschen und nur diese eine Datei behalten. <div> Schick es zurück.

const App = () => {
return <div className='chat-app'></div>
}

Wir beginnen damit, unsere Komponenten von unten nach oben zu erstellen.

Schritt 2: Komponente

In ChatLine.js erstellen wir eine neue Komponente mit zwei Eigenschaften:

  • Name: Zeichenkette
  • Nachricht: Zeichenkette

Dies sind die Daten, die wir später vom Server als Ereignisdaten erhalten werden.

Komponente Eins

  • Es gibt einfach einen Wert zurück und zeigt Name und Nachricht an:

    import React from 'react'
    const ChatLine = ({ name, message }) => {
    return (
    <li>
    {name}: {message}
    </li>
    )
    }
    export default

    Hinweis: ReactJS verhindert automatisch HTML-Injection, Sie brauchen sich also keine Sorgen zu machen.

    Schritt 3: Komponente

    In ChatHolder.js erstellen wir eine neue Komponente, die nur eine Basisklasse benötigt:

    Zeilen: Array<{ name: string, message: string }>

    Wenn Linien Wenn das Feld leer ist, zeigen wir eine einfache Benachrichtigung an.

    if (lines.length === 0) {
    return <div>Chat history is empty</div>
    }

    `Lines` ist ein Array von Objekten. Jedes Objekt besitzt einen Namen und die Eigenschaft `message`. Wir durchlaufen alle Elemente des Arrays, um das Ergebnis zu erhalten, indem wir den Namen und die Zeichenkette an die Komponente übergeben. Erstelle mehrere ChatLine-Knoten.

    const chatLines = lines.map(
    (line, index) => (
    <ChatLine key={index} name={line.name} message={line.message} />
    )
    )

    Dann das Ergebnis in einem

      Wir rendern die Komponente und erhalten so das fertige Ergebnis:

      import React from 'react'
      import ChatLine from './ChatLine'
      const ChatLineHolder = ({ lines }) => {
      if (lines.length === 0) {
      return <div>Chat history is empty</div>
      }
      const chatLines = lines.map(
      (line, index) => (
      <ChatLine key={index} message={line.message} name={line.name} />
      )
      )
      return (
      <ul>
      {chatLines}
      </ul>
      )
      }
      export default ChatLineHolder

      Hinweis: Normalerweise verwendet man einen eindeutigen Bezeichner als Schlüssel. In diesem Fall können wir bedenkenlos den Index verwenden, da sich die Zuordnung zwischen Index und Objekt nicht ändert. In realen Anwendungen ist dies jedoch sehr ärgerlich.

      Schritt 4: Komponente

      Wie Sie vielleicht bemerkt haben, gibt es immer noch keine Möglichkeit, Nachrichten zu importieren. Verarbeitet Texteingaben und verwendet beim Absenden eine Callback-Funktion, um beim Klicken auf den Button eine neue Chatnachricht zu öffnen. Erfordert eine Prop:

      • onSend: (message: string) => void

      Die Benutzereingabekomponente behält ihren Zustand bei und verwaltet Aktualisierungen.

      const [value, setValue] = useState('')
      const onChange = (event) => {
      setValue(event.target.value)
      }

      Beim Klicken auf den Absenden-Button wird die Funktion `onSend` mit dem aktuellen Zustand aufgerufen. Da wir nicht möchten, dass der Benutzer das Eingabefeld manuell leeren muss, setzen wir den Zustand nach dem Aufruf von `onSend` zurück.

      const onClickSend = () => {
      onSend(value)
      setValue('')
      }
      

      Hier ist die letzte Komponente:

      import React, { useState } from 'react'
      const ChatInput = ({ onSend }) => {
      const [value, setValue] = useState('')
      const onChange = (event) => {
      setValue(event.target.value)
      }
      const onClickSend = () => {
      setValue('')
      onSend(value)
      }
      return (
      <div>
      <input type='text' value={value} onChange={onChange} />
      <button onClick={onClickSend}>send</button>
      </div>
      )
      }
      export default ChatInput

      Schritt 5: Komponente

      Modus

      Da unsere Komponenten keine Daten speichern, Als Hauptkomponente verwenden wir sie zur Zustandsverwaltung. Wir haben 3 Arten von Zuständen:

      • Name: Der Name des Benutzers, der chattet.
      • chatLines: Ein Array, das den Chatverlauf darstellt.
      • eventListener: Wird verwendet, um Ereignisse vom Server zu verwalten. (Hinweis: Ich habe mich entschieden, den Listener in den entsprechenden Teil einzufügen.).

      (Der Einfachheit halber wäre in einer realen Anwendung möglicherweise ein anderer Ansatz ratsam.)

      Wir verwenden State Hooks, um unseren Zustand zu initialisieren:

       const [chatLines, setChatLines] = useState([])
      const [eventListener, setEventListener] = useState(null)
      const [name] = useState(generateRandomName())

      Komponenten-Rendering-Test

      Im Moment zeigen wir nur unseren Namen und die Komponente an. Wir präsentieren den Chatzeilen feste Elemente. Da Chatzeilen ein leeres Array ist, muss unsere Benachrichtigung bereitgestellt werden. Wir rufen eine leere Flash-Funktion auf, um Wir werden es senden. Die Ausführung erfolgt im nächsten Schritt.

      return (
      <div className='chat-app'>
      <h2>Chatting as {name}</h2>
      <ChatLineHolder lines={chatLines} />
      <ChatInput onSend={() => {}} />
      </div>
      )

      Wenn Sie überprüfen möchten, ob Ihre Implementierung mit einigen Daten funktioniert, fügen Sie einfach ein paar Elemente zu chatLines hinzu.

      const [chatLines, setChatLines] = useState([{ name: 'Thomas', 'message': 'Hi' }])
      

      Interaktion hinzufügen

      Wir können bereits Text in unser Chat-Eingabefeld eingeben, aber das Drücken von „Senden“ bewirkt nichts. Das liegt daran, dass wir eine Funktion namens „…“ haben. Wir haben etwas gesendet, das absolut nichts bewirkt. Daher benötigen wir eine Implementierung dafür.

      Da wir noch nicht mit unserem Server verbunden sind, implementieren wir unsere onSend-Methode so, dass der Zustand direkt aktualisiert wird. Dazu fügen wir die Hilfsfunktion addChatLine: (chatLine) => void hinzu. Diese verwenden wir später, um vom Server gesendete Nachrichtenereignisse zu verarbeiten.

      const addChatLine = (chatLine) => {
      setChatLines(chatLines => {
      return [...chatLines, chatLine]
      })
      // If you don't have a lot of experience with ReactJS, just think of this as:
      // setChatLines([...chatLines, chatLine])
      }

      onSend erstellt ein Chatline-Objekt und ruft addChatLine auf.

      const onSend = (message) => {
      const chatLine = { name, message }
      addChatLine(chatLine)
      }

      Vergiss nicht, es zu senden an Schicken.

      return (
      <div className='chat-app'>
      <h2>Chatting as {name}</h2>
      <ChatLineHolder lines={chatLines} />
      <ChatInput onSend={onSend} />
      </div>
      )

      Sie sollten nun in der Lage sein, Text in das Eingabefeld einzugeben, auf „Senden“ zu klicken und Ihre Nachricht sofort zu sehen.

      Schritt 6: Verbindung zum Server herstellen

      Sich selbst zu unterhalten ist sehr langweilig. Deshalb müssen wir unsere Anwendung mit dem Server verbinden. Dies geschieht in zwei Schritten:

      • Nachricht an Server senden
      • Abonnieren Sie die vom Server gesendeten Ereignisse.
      Nachricht an Server senden

      Wir müssen die von uns geschriebene onSend-Funktion anpassen. Wir können den gesamten Body durch einen einfachen Fetch-Aufruf ersetzen, der unseren Namen und unsere Nachricht im Body sendet. Wichtig ist, addChatLine nicht aufzurufen, da wir dies später tun, sobald wir das vom Server gesendete Ereignis empfangen.

      const onSend = async (message) => {
      fetch('http://localhost:4000/say',
      {
      headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      },
      method: 'post',
      mode: 'no-cors',
      body: `name=${name}&message=${message}`
      })
      }

      Wenn Sie jetzt auf „Absenden“ klicken, wird eine Anfrage an den Server gesendet, Ihr Status wird aber noch nicht aktualisiert! Wir kümmern uns im nächsten Schritt darum.

      Abonnieren Sie die vom Server gesendeten Ereignisse.

      Bevor wir Ereignisse abfangen, benötigen wir eine Funktion, die solche Nachrichtenereignisse verarbeitet. Da wir später Nachrichtenereignisse abfangen werden, können wir sie entsprechend implementieren. Sie nimmt einfach `event.data` entgegen, parst es in ein Objekt und ruft `addChatLine` auf.

      const onMessage = (event) => {
      const chatLine = JSON.parse(event.data)
      addChatLine(chatLine)
      }
      

      Um vom Server gesendete Ereignisse zu empfangen, erstellen wir ein Objekt der Klasse `EventSource` mit unserer lokalen Adresse. Anschließend fügen wir einen Ereignis-Listener für den Nachrichtentyp hinzu. Dann umschließen wir ihn mit einem `useEffect`-Hook (dies stellt sicher, dass die Komponente beim Aufruf von `useEffect` ausgelöst wird). Es wird eingebunden, die Ereignisquelle wird initialisiert und anschließend wieder geschlossen.

      useEffect(() => {
      let source = new EventSource('http://localhost:4000/listen')
      source.addEventListener('message', onMessage)
      setEventSource(source)
      return () => { source.close() }
      }, [])

      Komponente Schließlich sieht es so aus:

      import React, { useEffect, useState } from 'react'
      import ChatLineHolder from './ChatLineHolder'
      import ChatInput from './ChatInput'
      const App = () => {
      const [chatLines, setChatLines] = useState([])
      const [eventSource, setEventSource] = useState(null)
      const [name] = useState(generateRandomName())
      const addChatLine = (chatLine) => {
      setChatLines(chatLines => [...chatLines, chatLine])
      }
      const onMessage = (event) => {
      const chatLine = JSON.parse(event.data)
      addChatLine(chatLine)
      }
      useEffect(() => {
      let source = new EventSource("http://localhost:4000/listen")
      source.addEventListener('message', onMessage)
      setEventSource(source)
      return () => { source.close() }
      }, [])
      const onSend = (message) => {
      fetch(
      `http://localhost:4000/say`,
      {
      headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      },
      method: "post",
      mode: 'no-cors',
      body: `name=${name}&message=${message}`,
      })
      }
      return (
      <div className='chat-app'>
      <h2>Chatting as {name}</h2>
      <ChatLineHolder lines={chatLines} />
      <ChatInput onSend={onSend} />
      </div>
      )
      }
      export default App

      Ergebnis

      Jetzt können Sie Ihre Seite in zwei Tabs öffnen und mit zwei Alter Egos chatten! Sie können die App-Komponente auch zweimal einbinden (indem Sie die index.js-Datei ändern), da jede Instanz ihren eigenen Zustand hat.

  • Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

    Das könnte Ihnen auch gefallen