Tutorial

Erstellen von benutzerdefinierten Komponenten in React

DevelopmentJavaScriptProgramming ProjectReact

Der Autor hat Creative Commons dazu ausgewählt, im Rahmen des Programms Write for DOnations eine Spende zu erhalten.

Einführung

In diesem Tutorial lernen Sie, wie Sie in React benutzerdefinierte Komponenten erstellen können. Komponenten sind voneinander unabhängige Funktionselemente, die Sie in Ihrer Anwendung wiederverwenden können, und stellen die Grundbausteine aller React-Anwendungen dar. Häufig können sie aus einfachen JavaScript-Funktionen und -Klassen bestehen, aber Sie verwenden sie so, als wären sie angepasste HTML-Elemente. Schaltflächen, Menüs und alle anderen Frontend-Seiteninhalte können als Komponenten erstellt werden. Komponenten können auch Statusinformationen und Display-Markdown enthalten.

Nach dem Erlernen der Erstellung von Komponenten in React können Sie komplexe Anwendungen in kleine Teile aufteilen, die sich leichter einrichten und pflegen lassen.

In diesem Tutorial erstellen Sie eine Liste von Emojis, deren Namen angezeigt werden, wenn Sie darauf klicken. Die Emojis werden unter Verwendung einer benutzerdefinierten Komponente erstellt und aus einer anderen benutzerdefinierten Komponente heraus aufgerufen. Am Ende dieses Tutorials haben Sie mithilfe von JavaScript-Klassen und JavaScript-Funktionen benutzerdefinierte Komponenten erstellt und wissen, wie Sie bestehenden Code in wiederverwendbare Stücke aufteilen und die Komponenten in einer lesbaren Dateistruktur speichern können.

Voraussetzungen

Schritt 1 — Einrichten des React-Projekts

In diesem Schritt erstellen Sie unter Verwendung von Create React App eine Grundlage für Ihr Projekt. Sie werden das Standardprojekt ändern, um Ihr Basisprojekt zu erstellen, indem Sie ein Mapping über eine Liste von Emojis vornehmen und etwas Styling hinzufügen.

Erstellen Sie zuerst ein neues Projekt. Öffnen Sie ein Terminal und führen Sie dann den folgenden Befehl aus:

  • npx create-react-app tutorial-03-component

Wechseln Sie danach in das Projektverzeichnis:

  • cd tutorial-03-component

Öffnen Sie den App.js-Code in einem Texteditor:

  • nano src/App.js

Erstellen Sie als Nächstes den von Create React App erstellten Vorlagencode und ersetzen Sie dann den Inhalt durch neuen React-Code, der eine Liste von Emojis anzeigt:

tutorial-03-component/src/App.js
import React from 'react';
import './App.css';

const displayEmojiName = event => alert(event.target.id);
const emojis = [
  {
    emoji: '😀',
    name: "test grinning face"
  },
  {
    emoji: '🎉',
    name: "party popper"
  },
  {
    emoji: '💃',
    name: "woman dancing"
  }
];

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

Dieser Code verwendet die Syntax von JSX, um mithilfe von map() über das emojis array zu mappen und sie als <li>-Listenelemente aufzulisten. Außerdem fügt er onClick-Ereignisse an, um Emoji-Daten im Browser anzuzeigen. Um den Code näher kennenzulernen, konsultieren Sie Erstellen von React-Elementen mit JSX, wo Sie eine detaillierte Erklärung zu JSX finden.

Speichern und schließen Sie die Datei. Sie können die Datei logo.svg nun löschen, da sie Teil der Vorlage war und Sie nicht mehr auf sie verweisen:

  • rm src/logo.svg

Aktualisieren Sie nun das Styling. Öffnen Sie src/App.css:

  • nano src/App.css

Ersetzen Sie den Inhalt mit dem folgenden CSS, um die Elemente zu zentrieren und die Schrift anzupassen:

tutorial-03-component/src/App.css
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

button {
    font-size: 2em;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}

ul {
    display: flex;
    padding: 0;
}

li {
    margin: 0 20px;
    list-style: none;
    padding: 0;
}

Dabei wird flex zum Zentrieren des Hauptelements <h1> und der Listenelemente verwendet. Außerdem werden standardmäßige Schaltflächenstile und <li>-Stile entfernt, damit die Emojis in einer Reihe angezeigt werden. Weitere Informationen finden Sie unter Erstellen von React-Elementen mit JSX.

Speichern und schließen Sie die Datei.

Öffnen Sie ein anderes Terminalfenster im Stammverzeichnis Ihres Projekts. Starten Sie das Projekt mit dem folgenden Befehl:

  • npm start

Nach der Ausführung des Befehls sehen Sie, dass das Projekt in Ihrem Webbrowser unter http://localhost:3000 ausgeführt wird.

Lassen Sie dies die ganze Zeit, die Sie an Ihrem Projekt arbeiten, laufen. Bei jeder Speicherung des Projekts wird der Browser automatisch aktualisiert und zeigt den aktuellsten Code an.

Sie werden Ihre Projektseite mit Hello, World und den drei Emojis sehen, die Sie in Ihrer App.js-Datei aufgeführt haben:

Browser mit Emoji

Nachdem Sie Ihren Code eingerichtet haben, können Sie nun mit der Zusammenstellung von Komponenten in React beginnen.

Schritt 2 — Erstellen einer unabhängigen Komponente mit React-Klassen

Nachdem Ihr Projekt nun ausgeführt wird, können Sie damit beginnen, Ihre benutzerdefinierte Komponente zu erstellen. In diesem Schritt erstellen Sie eine unabhängige React-Komponente, indem Sie die grundlegende React Component-Klasse erweitern. Sie werden eine neue Klasse erstellen, Methoden hinzufügen und die Renderingfunktion zum Anzeigen von Daten verwenden.

React-Komponenten sind in sich geschlossene Elementen, die Sie in allen Bereichen einer Seite wiederverwenden können. Indem Sie kleine, fokussierte Codestücke erstellen, können Sie Stücke verschieben und wiederverwenden, wenn Ihre Anwendung wächst. Das Entscheidende ist, dass sie in sich geschlossen und fokussiert sind, sodass Sie Code in logische Teile trennen können. Sie haben in Wahrheit bereits mit logisch getrennten Komponenten gearbeitet: Die App.js-Datei ist eine funktionelle Komponente, über die Sie in Schritt 3 mehr erfahren werden.

Es gibt zwei Arten von benutzerdefinierten Komponenten: klassenbasiert und funktional. Die erste Komponente, die Sie erstellen werden, ist eine klassenbasierte Komponente. Sie werden eine neue Komponente namens Instructions erstellen, die die Anweisungen für den Emoji-Viewer erklärt.

Anmerkung: Klassenbasierte Komponenten waren einmal die beliebteste Möglichkeit zur Erstellung von React-Komponenten. Seit der Einführung von React Hooks wechseln jedoch viele Entwickler und Bibliotheken zur Verwendung funktionaler Komponenten.

Obwohl funktionale Komponenten inzwischen die Norm sind, werden Sie in älterem Code oft Klassenkomponenten finden. Sie müssen sie nicht verwenden, aber wissen, wie Sie sie erkennen können. Außerdem liefern sie eine verständliche Einführung in viele zukünftige Konzepte, wie z. B. Zustandsverwaltung. In diesem Tutorial lernen Sie, sowohl Klassen- als auch Funktionskomponenten einzurichten.

Erstellen Sie zuerst eine neue Datei. Der Konvention nach werden Komponentendateien großgeschrieben:

  • touch src/Instructions.js

Öffnen Sie die Datei dann in Ihrem Texteditor:

  • nano src/Instructions.js

Importieren Sie zuerst React und die Component-Klasse und exportieren Sie Instructions mit den folgenden Zeilen:

tutorial-03-component/src/Instructions.js
import React, { Component } from 'react';

export default class Instructions extends Component {}

Durch Importieren von React wird die JSX konvertiert. Component ist eine Basisklasse, die Sie zur Erstellung Ihrer Komponente erweitern werden. Dazu haben Sie eine Klasse erstellt, die den Namen Ihrer Komponente (Instructions) trägt, und die Basis-Component mit der Zeile export erweitert. Außerdem exportieren Sie diese Klasse mit export default am Anfang der Klassendeklaration als Standard.

Der Klassenname sollte großgeschrieben sein und mit dem Namen der Datei übereinstimmen. Das ist wichtig, wenn Sie Debugging-Tools verwenden, die den Namen der Komponente anzeigen. Wenn der Name mit der Dateistruktur übereinstimmt, ist es leichter, die entsprechende Komponente zu finden.

Die grundlegende Component-Klasse bietet verschiedene Methoden, die Sie in Ihrer benutzerdefinierten Klasse verwenden können. Die wichtigste Methode und die einzige, die Sie in diesem Tutorial verwenden werden, ist die Methode render(). Die Methode render() gibt den JSX-Code aus, den Sie im Browser anzeigen möchten.

Fügen Sie zuerst eine kleine Erklärung der App in einem <p>-Tag hinzu:

tutorial-03-component/src/Instructions.js
import React, { Component } from 'react';

export class Instructions extends Component {

  render() {
    return(
      <p>Click on an emoji to view the emoji short name.</p>
    )
  }

}

Speichern und schließen Sie die Datei. Zu diesem Zeitpunkt gibt es immer noch keine Änderung in Ihrem Browser. Das liegt daran, dass Sie die neue Komponente noch nicht verwendet haben. Um die Komponente zu nutzen, müssen Sie sie in eine weitere Komponente einfügen, die mit der Stammkomponente verbunden ist. In diesem Projekt ist <App> die Stammkomponente in index.js. Um sie in Ihrer Anwendung sichtbar zu machen, müssen Sie sie der <App>-Komponente hinzufügen.

Öffnen Sie src/App.js in einem Texteditor:

  • nano src/App.js

Zuerst müssen Sie die Komponente importieren:

tutorial-03-component/src/App.js
import React from 'react';

import Instructions from './Instructions';

import './App.css';

...

export default App;

Da es sich dabei um den Standardimport handelt, können Sie mit jedem gewünschten Namen importieren. Am besten ist es, die Namen für einfache Lesbarkeit konsistent zu halten: Der Import sollte mit dem Komponentennamen übereinstimmen, der mit dem Dateinamen übereinstimmen sollte. Die einzige feste Regel besteht darin, dass die Komponente mit einem Großbuchstaben beginnen muss. So weiß React, dass es sich um eine React-Komponente handelt.

Nachdem Sie die Komponente importiert haben, fügen Sie sie jetzt zum Rest Ihres Codes hinzu, als wäre sie ein benutzerdefiniertes HTML-Element:

tutorial-03-component/src/App.js
import React from 'react';

import Instructions from './Instructions.js'

...
function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

In diesem Code haben Sie die Komponente mit spitzen Klammern umschlossen. Da diese Komponente keine untergeordneten Komponenten aufweist, kann sie sich selbst schließen, indem sie auf /> endet.

Speichern Sie die Datei. Wenn Sie dies tun, wird die Seite aktualisiert und Sie werden die neue Komponente sehen.

Browser mit Anweisungstext

Nachdem Sie über Text verfügen, können Sie nun ein Bild hinzufügen. Laden Sie ein Emoji-Bild von Wikimedia herunter und speichern Sie es mit folgendem Befehl im Verzeichnis src als emoji.svg:

  • curl -o src/emoji.svg https://upload.wikimedia.org/wikipedia/commons/3/33/Twemoji_1f602.svg

curl richtet die Anfrage an die URL und mit dem -o-Flag können Sie Datei als src/emoji.svg speichern.

Öffnen Sie anschließend Ihre Komponentendatei:

  • nano src/Instructions.js

Importieren Sie das Emoji und fügen Sie es mit einem dynamischen Link Ihrer benutzerdefinierten Komponente hinzu:

tutorial-03-component/src/Instructions.js
import React, { Component } from 'react';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <>
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </>
    )
  }
}

Beachten Sie, dass Sie beim Importieren die Dateierweiterung .svg einfügen müssen. Beim Import importieren Sie einen dynamischen Pfad, der von webpack bei der Kompilierung des Codes erstellt wird. Weitere Informationen finden Sie unter Einrichten eines React-Projekts mit Create React App.

Außerdem müssen Sie die Tags <img> und <p> mit leeren Tags umschließen, um sicherzustellen, dass Sie ein einzelnes Element zurückgeben.

Speichern Sie die Datei. Wenn Sie neu laden, wird das Bild im Vergleich zum Rest des Inhalts sehr groß dargestellt:

Browserfenster mit großem Emoji-Bild

Um das Bild zu verkleinern, müssen Sie Ihrer benutzerdefinierten Komponente CSS und einen className hinzufügen.

Ändern Sie zuerst in Instructions.js die leeren Tags in ein div und vergeben Sie den className instructions:

tutorial-03-component/src/Instructions.js
import React, { Component } from 'react';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

Speichern und schließen Sie die Datei. Öffnen Sie als Nächstes App.css:

  • nano src/App.css

Erstellen Sie Regeln für den .instructions-Klassenselektor:

tutorial-03-component/src/App.css
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

...

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

Wenn Sie ein display im Styling von flex hinzufügen, zentrieren Sie img und das p mit Flexbox. Sie haben die Richtung geändert, sodass mit flex-direction: column; alles vertikal ausgerichtet ist. Die Zeile align-items: center; wird die Elemente auf dem Bildschirm zentrieren.

Nachdem Ihre Elemente ausgerichtet sind, müssen Sie die Bildgröße ändern. Geben Sie dem img innerhalb des div eine width (Breite) und height (Höhe) von 100px.

tutorial-03-component/src/App.css
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

...

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.instructions img {
    width: 100px;
    height: 100px;
}

Speichern und schließen Sie die Datei. Der Browser wird neu geladen und Sie sehen, dass das Bild wesentlich kleiner ist:

Browserfenster mit kleinerem Bild

Nun haben Sie eine unabhängige und wiederverwendbare benutzerdefinierte Komponente erstellt. Um zu sehen, wie sie sich wiederverwenden lässt, fügen Sie eine zweite Instanz zu App.js hinzu.

Öffnen Sie App.js:

  • nano src/App.js

Fügen Sie in App.js eine zweite Instanz der Komponente hinzu:

tutorial-03-component/src/App.js
import React from 'react';

import Instructions from './Instructions.js'

...

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

Speichern Sie die Datei. Wenn der Browser neu geladen wird, sehen Sie die Komponente zweimal.

Browser mit zwei Instanzen der Instructions-Komponente

In diesem Fall benötigen Sie keine zwei Instanzen von Instructions, aber Sie können sehen, dass sich die Komponente effizient wiederverwenden lässt. Wenn Sie benutzerdefinierte Schaltflächen oder Tabellen erstellen, verwenden Sie sie auf einer Seite wahrscheinlich mehrfach. Somit eignen sie sich perfekt für benutzerdefinierte Komponenten.

Zunächst können Sie das zusätzliche Bild-Tag löschen. Löschen Sie in Ihrem Texteditor die zweiten <Instructions /> und speichern Sie die Datei:

tutorial-03-component/src/App.js
import React from 'react';

import Instructions from './Instructions.js'

...

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

Sie verfügen nun über eine wiederverwendbare, unabhängige Komponente, die Sie in einer übergeordneten Komponente mehrfach hinzufügen können. Die Struktur, die Sie jetzt haben, funktioniert für eine kleine Anzahl von Komponenten; es gibt da aber ein kleines Problem. Alle Dateien sind zusammengemischt. Das Bild für <Instructions> befindet sich im gleichen Verzeichnis wie die Assets für <App>. Außerdem vermischen Sie den CSS-Code für <App> mit dem CSS-Code für <Instructions>.

Im nächsten Schritt erstellen Sie eine Dateistruktur, die jeder Komponente Unabhängigkeit verleiht, indem ihre Funktionen, Stile und Abhängigkeiten gruppiert werden. Damit können Sie sie wie erforderlich verschieben.

Schritt 3 — Erstellen einer lesbaren Dateistruktur

In diesem Schritt erstellen Sie eine Dateistruktur, um Ihre Komponenten und ihre Assets (wie Bilder, CSS und andere JavaScript-Dateien) zu organisieren. Sie werden Code nach Komponenten gruppieren, nicht nach Asset-Typ. Anders ausgedrückt: Sie werden kein separates Verzeichnis für CSS, Bilder und JavaScript nutzen. Stattdessen verfügen Sie über ein separates Verzeichnis für jede Komponente, das den entsprechenden CSS-Code, JavaScript und Bilder enthält. In beiden Fällen sorgen Sie für eine Trennung von Bedenken.

Da Sie über eine unabhängige Komponente verfügen, benötigen Sie eine Dateistruktur, die den entsprechenden Code gruppiert. Derzeit befindet sich alles im gleichen Verzeichnis. Listen Sie die Elemente in Ihrem src-Verzeichnis auf:

  • ls src/

Die Ausgabe zeigt, dass alles ziemlich durcheinander ist:

Output
App.css Instructions.js index.js App.js emoji.svg serviceWorker.js App.test.js index.css setupTests.js

Sie sehen Code für die <App>-Komponente (App.css, App.js und App.test.js) neben Ihrer Stammkomponente (index.css und index.js) sowie Ihrer benutzerdefinierten Komponente Instructions.js.

React ist absichtlich agnostisch hinsichtlich der Dateistruktur. React empfiehlt keine spezielle Struktur und das Projekt kann mit einer Vielzahl verschiedener Dateihierarchien arbeiten. Wir empfehlen jedoch, für Ordnung zu sorgen, um ein Überladen Ihres Stammverzeichnisses mit Komponenten, CSS-Dateien und Bildern zu vermeiden. So können Sie die Navigation erleichtern. Außerdem kann eine explizite Benennung leichter sichtbar machen, welche Teile Ihres Projekts verwandt sind. Beispielsweise ist eine Bilddatei namens Logo.svg möglicherweise nicht eindeutig Teil einer Komponente namens Header.js.

Eine der einfachsten Strukturen besteht darin, ein Verzeichnis components mit einem separaten Verzeichnis für jede Komponente zu erstellen. Dadurch können Sie Ihre Komponenten getrennt von Ihrem Konfigurationscode (wie z. B. serviceWorker) anordnen und die Assets mit den Komponenten gruppieren.

Erstellen eines Verzeichnisses namens Components

Erstellen Sie zuerst ein Verzeichnis namens Components:

  • mkdir src/components

Verschieben Sie als Nächstes die folgenden Komponenten und Code in das Verzeichnis: App.css, App.js, App.test.js, Instructions.js und emoji.svg:

  • mv src/App.* src/components/
  • mv src/Instructions.js src/components/
  • mv src/emoji.svg src/components/

Hier verwenden Sie einen Platzhalter (*) zur Auswahl aller mit App. beginnenden Dateien.

Nachdem Sie den Code verschoben haben, sehen Sie einen Fehler in Ihrem Terminal, in dem npm start ausgeführt wird.

Output
Failed to compile. ./src/App.js Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/App.js'

Denken Sie daran, dass der gesamte Code unter Verwendung von relativen Pfaden importiert. Wenn Sie den Pfad für einige Dateien ändern, müssen Sie den Code aktualisieren.

Dazu öffnen Sie index.js.

  • nano src/index.js

Ändern Sie dann den Pfad des App-Imports, um aus dem Verzeichnis components/ zu importieren.

tutorial-03-component/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import * as serviceWorker from './serviceWorker';

...

serviceWorker.unregister();

Speichern und schließen Sie die Datei. Ihr Skript wird die Änderungen erkennen und der Fehler verschwindet.

Nun verfügen Sie über Komponenten in einem separaten Verzeichnis. Wenn Ihre Anwendungen komplexer werden, verfügen Sie möglicherweise über Verzeichnisse für API-Dienste, Datenspeicher und Dienstprogrammfunktionen. Die Trennung von Komponentencode ist der erste Schritt, aber da gibt es noch CSS-Code für Instructions vermischt in der Datei App.css. Um diese logische Trennung zu erstellen, werden Sie die Komponenten zuerst in separate Verzeichnisse verschieben.

Verschieben von Komponenten in einzelne Verzeichnisse

Erstellen Sie zuerst ein Verzeichnis speziell für die <App>-Komponente:

  • mkdir src/components/App

Verschieben Sie dann die verwandten Dateien in das neue Verzeichnis:

  • mv src/components/App.* src/components/App

Wenn Sie das tun, erhalten Sie einen ähnlichen Fehler wie im letzten Abschnitt:

Output
Failed to compile. ./src/components/App.js Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/components/App.js'

In diesem Fall müssen Sie zwei Dinge aktualisieren. Zuerst müssen Sie den Pfad in index.js aktualisieren.

Öffnen Sie die Datei index.js:

  • nano src/index.js

Aktualisieren Sie dann den Importpfad für App, um auf die Komponente App im Verzeichnis App zu verweisen.

tutorial-03-component/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App/App';
import * as serviceWorker from './serviceWorker';

...

serviceWorker.unregister();

Speichern und schließen Sie die Datei. Die Anwendung wird immer noch nicht ausgeführt. Ihnen wird ein Fehler angezeigt, der wie folgt aussieht:

Output
Failed to compile. ./src/components/App/App.js Module not found: Can't resolve './Instructions.js' in 'your_file_path/tutorial-03-component/src/components/App'

Da sich <Instructions> nicht auf der gleichen Verzeichnisebene wie die <App>-Komponente befindet, müssen Sie den Importpfad ändern. Erstellen Sie zuvor ein Verzeichnis für Instructions. Erstellen Sie ein Verzeichnis namens Instructions im Verzeichnis src/components:

  • mkdir src/components/Instructions

Verschieben Sie dann Instructions.js und emoji.svg in dieses Verzeichnis:

  • mv src/components/Instructions.js src/components/Instructions
  • mv src/components/emoji.svg src/components/Instructions

Nachdem das Komponentenverzeichnis Instructions nun erstellt wurde, können Sie die Aktualisierung der Dateipfade abschließen, um Ihre Komponente mit Ihrer App zu verbinden.

Aktualisieren von import-Pfaden

Nachdem sich die Komponenten in einzelnen Verzeichnissen befinden, können Sie nun den Importpfad in App.js anpassen.

Öffnen Sie App.js:

  • nano src/components/App/App.js

Da der Pfad relativ ist, müssen Sie ein Verzeichnis –src/components – nach oben und dann in das Verzeichnis Instructions für Instructions.js gehen. Da dies jedoch eine JavaScript-Datei ist, benötigen Sie den letzten Import nicht.

tutorial-03-component/src/components/App/App.js
import React from 'react';

import Instructions from '../Instructions/Instructions.js';

import './App.css';

...

export default App;

Speichern und schließen Sie die Datei. Nachdem Ihre Importe nun den richtigen Pfad verwenden, wird Ihr Browser aktualisiert und zeigt die Anwendung an.

Browserfenster mit kleinerem Bild

Anmerkung: Sie können die Stammdatei auch in jedem Verzeichnis-index.js aufrufen. Anstelle von src/components/App/App.js könnten Sie beispielsweise src/components/App/index.js erstellen. Der Vorteil dabei besteht darin, dass Ihre Importe etwas kleiner ausfallen. Wenn der Pfad auf ein Verzeichnis verweist, wird der Import nach einer index.js-Datei suchen. Der Import für src/components/App/index.js in der Datei src/index.js wäre import ./components/App. Der Nachteil dieses Ansatzes besteht darin, dass Sie viele Dateien mit dem gleichen Namen erhalten. Das kann das Lesen in einigen Texteditoren erschweren. Letztendlich ist es eine persönliche Entscheidung bzw. Entscheidung im Team; es wird jedoch empfohlen, konsistent zu sein.

Trennen von Code in freigegebenen Dateien

Nun verfügt jede Komponente über ein eigenes Verzeichnis, aber nicht alles ist vollkommen unabhängig voneinander. Der letzte Schritt besteht darin, das CSS für Instructions in eine separaten Datei zu extrahieren.

Erstellen Sie zuerst eine CSS-Datei in src/components/Instructions:

  • touch src/components/Instructions/Instructions.css

Öffnen Sie die CSS-Datei dann in Ihrem Texteditor:

  • nano src/components/Instructions/Instructions.css

Fügen Sie das Instructions-CSS hinzu, den Sie in einem früheren Abschnitt erstellt haben:

tutorial-03-component/src/components/Instructions/Instructions.css
.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.instructions img {
    width: 100px;
    height: 100px;
}

Speichern und schließen Sie die Datei. Entfernen Sie anschließend das Instuctions-CSS aus src/components/App/App.css.

  • nano src/components/App/App.css

Entfernen Sie die Zeilen über .instructions. Die endgültige Datei sieht so aus:

tutorial-03-component/src/components/App/App.css
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

button {
    font-size: 2em;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}

ul {
    display: flex;
    padding: 0;
}

li {
    margin: 0 20px;
    list-style: none;
    padding: 0;
}

Speichern und schließen Sie die Datei. Importieren Sie abschließend das CSS in Instructions.js:

  • nano src/components/Instructions/Instructions.js

Importieren Sie das CSS unter Verwendung des relativen Pfads:

tutorial-03-component/src/components/Instructions/Instructions.js
import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

Speichern und schließen Sie die Datei. Ihr Browserfenster wird wie zuvor aussehen; allerdings sind jetzt alle Dateiressourcen im gleichen Verzeichnis angeordnet.

Browserfenster mit kleinerem Bild

Sehen Sie sich am Ende noch einmal die Struktur an. Zuerst das Verzeichnis src/:

  • ls src

Sie verfügen über die Stammkomponente index.js und das verwandten CSS index.css neben dem Verzeichnis components/ und Dienstprogrammdateien wie serviceWorker.js und setupTests.js:

Output
components serviceWorker.js index.css setupTests.js index.js

Sehen Sie anschließend in components nach:

  • ls src/components

Sie werden für jede Komponente ein Verzeichnis sehen:

Output
App Instructions

Wenn Sie in den einzelnen Komponenten nachsehen, finden Sie den Komponentencode, CSS, Test und Bilddateien (so vorhanden).

  • ls src/components/App
Output
App.css App.js App.test.js
  • ls src/components/Instructions
Output
Instructions.css Instructions.js emoji.svg

Nun haben Sie eine solide Struktur für Ihr Projekt erstellt. Sie haben viel Code verschoben. Jetzt verfügen Sie aber über eine Struktur, die das Skalieren einfacher macht.

Das ist nicht die einzige Methode, mit der Sie Ihre Struktur konzipieren können. Einige Dateistrukturen können Codetrennung nutzen, indem ein Verzeichnis angegeben wird, das in verschiedene Pakete aufgeteilt wird. Andere Dateistrukturen werden nach Route aufgeteilt und nutzen ein gemeinsames Verzeichnis für Komponenten, die über verschiedene Routen hinweg verwendet werden.

Beginnen Sie vorerst mit einem weniger komplexen Ansatz. Wenn sich ein Bedarf nach einer anderen Struktur ergibt, ist es immer leichter, von einfach zu komplex zu gehen. Wenn Sie mit einer komplexen Struktur anfangen, bevor Sie sie benötigen, erschwert das das Refactoring.

Nachdem Sie eine klassenbasierte Komponente erstellt und organisiert haben, werden Sie im nächsten Schritt eine funktionale Komponente erstellen.

Schritt 4 — Erstellen einer funktionalen Komponente

In diesem Schritt erstellen Sie eine funktionale Komponente. Funktioale Komponenten sind die häufigsten Komponenten in aktuellem React-Code. Diese Komponenten sind meist kürzer und können im Gegensatz zu klassenbasierten Komponenten React-Hooks verwenden. Dabei handelt es sich um eine neue Form von Zustands- und Ereignisverwaltung.

Eine funktionale Komponente ist eine JavaScript-Funktion, die JSX zurückgibt. Sie muss nichts erweitern und es gibt keine speziellen Methoden, die Sie sich merken müssen.

Um <Instructions> als funktionale Komponente zu refaktorisieren, müssen Sie die Klasse in eine Funktion ändern und die Renderingmethode entfernen, damit nur noch die Return-Anweisung übrig bleibt.

Dazu öffnen Sie zuerst Instructions.js in einem Texteditor.

  • nano src/components/Instructions/Instructions.js

Ändern Sie die class-Deklaration in eine function-Deklaration:

tutorial-03-component/src/components/Instructions/Instructions.js
import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {
  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

Entfernen Sie anschließend den Import von { Component }:

tutorial-03-component/src/components/Instructions/Instructions.js
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

Entfernen Sie abschließend die Methode render(). Nun geben Sie nur JSX zurück.

tutorial-03-component/src/components/Instructions/Instructions.js
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {
  return(
    <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
    </div>
  )
}

Speichern Sie die Datei. Der Browser wird aktualisiert und Sie werden Ihre Seite wie zuvor sehen.

Browser mit Emoji

Sie könnten die Funktion auch als Pfeilfunktion neu schreiben, indem Sie die implizite Rückgabe verwenden. Der Hauptunterschied besteht darin, dass Sie den Funktionsrumpf verlieren. Außerdem müssen Sie die Funktion zuerst einer Variable zuweisen und dann die Variable exportieren:

tutorial-03-component/src/components/Instructions/Instructions.js
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

const Instructions = () => (
  <div className="instructions">
    <img alt="laughing crying emoji" src={emoji} />
    <p>Click on an emoji to view the emoji short name.</p>
  </div>
)

export default Instructions;

Einfache funktionale Komponenten und klassenbasierte Komponenten sind sich sehr ähnlich. Wenn Sie über eine einfache Komponente verfügen, die keinen Zustand speichert, ist es am besten, eine funktionale Komponente zu verwenden. Der wahre Unterschied besteht darin, wie sie den Zustand einer Komponente speichern und Eigenschaften nutzen. Klassenbasierte Komponenten verwenden Methoden und Eigenschaften, um den Zustand festzulegen, und sind meist etwas länger. Funktionale Komponenten nutzen zum Speichern des Zustands oder Verwalten von Änderungen Hooks und sind meist etwas kürzer.

Zusammenfassung

Nun verfügen Sie über eine kleine Anwendung mit voneinander unabhängigen Teilen. Sie haben zwei verbreitete Arten von Komponenten erstellt: Funktionale und Klassen. Sie haben Teile der Komponenten in Verzeichnisse aufgeteilt, damit Sie ähnliche Codestücke zusammen aufbewahren können. Außerdem haben Sie die Komponenten importiert und wiederverwendet.

Mit einem guten Verständnis der Komponenten können Sie sich Ihre Anwendungen nun als Teile vorstellen, die Sie auseinander nehmen und wieder zusammensetzen können. Projekte werden damit modular und austauschbar. Die Fähigkeit, ganze Anwendungen als Reihe von Komponenten zu betrachten, ist ein wichtiger Denkschritt in React. Wenn Sie weitere React-Tutorials konsultieren möchten, sehen Sie sich unsere React-Themenseite an oder kehren Sie zurück zur Seite der Reihe Codieren in React.js.

0 Comments

Creative Commons License