Tipps zum Schreiben prägnanter React-Komponenten

Tipps zum Schreiben prägnanter React-Komponenten

Dieser Artikel basiert auf dem übersetzten Artikel Einfache Tipps zum Schreiben sauberer React-Komponenten, der ursprüngliche Autor ist Iskander Samatov

In diesem Beitrag überprüfen wir einige einfache Techniken, die uns helfen, sauberere React-Komponenten zu schreiben und unsere Projekte besser zu skalieren.

Vermeiden Sie die Verwendung des Spread-Operators zum Übergeben von Requisiten

Beginnen wir zunächst mit einem Antimuster, das vermieden werden sollte. Sofern es keinen klaren Grund dafür gibt, sollten Sie es vermeiden, Props mit dem Spread-Operator durch den Komponentenbaum zu übergeben, z. B. { ...props } .

Das Übergeben von Requisiten auf diese Weise beschleunigt das Schreiben von Komponenten. Allerdings ist es für uns dadurch auch schwieriger, Fehler im Code zu finden. Dadurch verlieren wir das Vertrauen in die Komponenten, die wir schreiben, die Refaktorierung von Komponenten wird schwieriger und es können Fehler auftreten, die schwer zu debuggen sind.

Kapseln Sie Funktionsparameter in ein Objekt

Wenn eine Funktion mehrere Parameter akzeptiert, ist es am besten, sie in einem Objekt zu kapseln. Zum Beispiel:

export const sampleFunction = ({ param1, param2, param3 }) => {
  console.log({ param1, param2, param3 });
}

Das Schreiben von Funktionssignaturen auf diese Weise bietet mehrere wesentliche Vorteile:

  1. Sie müssen sich keine Gedanken mehr über die Reihenfolge machen, in der Parameter übergeben werden. Mir sind mehrere Fehler unterlaufen, die aufgrund der Reihenfolge der Übergabe der Funktionsparameter zu Bugs geführt haben.
  2. Bei Editoren, die mit intelligenten Eingabeaufforderungen konfiguriert sind (die meisten verfügen mittlerweile darüber), ist die automatische Vervollständigung von Funktionsparametern sehr gut möglich.

Für Ereignisverarbeitungsfunktionen verwenden Sie die Verarbeitungsfunktion als Rückgabewert der Funktion

Wenn Sie mit der funktionalen Programmierung vertraut sind, ähnelt diese Programmiertechnik dem Funktions-Currying, da einige Parameter bereits im Voraus festgelegt sind.

Schauen wir uns dieses Beispiel an:

React von „react“ importieren

exportiere Standardfunktion SampleComponent({ beiWertänderung }) {

  const handleChange = (Schlüssel) => {
    return (e) => beiWertänderung(Schlüssel, e.Ziel.Wert)
  }

  zurückkehren (
    <form>
      <input beiÄnderung={handleChange('name')} />
      <input onChange={handleChange('email')} />
      <input onChange={handleChange('Telefon')} />
    </form>
  )
}

Wie Sie sehen, bleibt der Komponentenbaum übersichtlich, wenn Sie die Handler-Funktion auf diese Weise schreiben.

Beim Rendern von Komponenten wird map anstelle von if/else verwendet.

Wenn Sie verschiedene Elemente basierend auf benutzerdefinierter Logik rendern müssen, empfehle ich die Verwendung von Map anstelle von if/else-Anweisungen.

Hier ist ein Beispiel mit if/else:

React von „react“ importieren

const Student = ({ name }) => <p>Name des Studenten: {name}</p>
const Teacher = ({ name }) => <p>Name des Lehrers: {name}</p>
const Guardian = ({ name }) => <p>Name des Wächters: {name}</p>

exportiere Standardfunktion SampleComponent({ Benutzer }) {
  lass Komponente = Student;
  wenn (Benutzer.Typ === 'Lehrer') {
    Komponente = Lehrer
  } sonst wenn (Benutzer.Typ === 'Wächter') {
    Komponente = Wächter
  }

  zurückkehren (
    <div>
      <Komponentenname={Benutzername} />
    </div>
  )
}

Hier ist ein Beispiel mit Karte:

React von „react“ importieren

const Student = ({ name }) => <p>Name des Studenten: {name}</p>
const Teacher = ({ name }) => <p>Name des Lehrers: {name}</p>
const Guardian = ({ name }) => <p>Name des Wächters: {name}</p>

const COMPONENT_MAP = {
  Student: Student,
  Lehrer: Lehrer,
  Wächter: Wächter
}

exportiere Standardfunktion SampleComponent({ Benutzer }) {
  const Component = COMPONENT_MAP[Benutzer.Typ]

  zurückkehren (
    <div>
      <Komponentenname={Benutzername} />
    </div>
  )
}

Mit dieser einfachen kleinen Strategie können Sie Ihre Komponenten lesbarer und verständlicher machen. Und es erleichtert auch die logische Erweiterung.

Hook-Komponenten

Dieser Modus ist sehr nützlich, solange er nicht missbraucht wird.

Möglicherweise verwenden Sie in Ihrer Anwendung viele Komponenten. Wenn für ihre Funktion ein bestimmter Zustand erforderlich ist, können Sie sie in einen Hook einbinden, der diesen Zustand bereitstellt. Einige gute Beispiele für diese Komponenten sind Popups, Toastbenachrichtigungen oder einfache modale Dialoge. Hier ist beispielsweise eine Hook-Komponente für einen einfachen Bestätigungsdialog:

importiere React, { useCallback, useState } von „react“;
importiere ConfirmationDialog aus „Komponenten/Global/ConfirmationDialog“;

Exportieren Sie die Standardfunktion useConfirmationDialog({
  HeaderText,
  Textkörper,
  BestätigungsButtonText,
  bei Klick bestätigen,
}) {
  const [isOpen, setIsOpen] = useState(false);

  const beim Öffnen = () => {
    setIsOpen(true);
  };

  const Dialog = useCallback(
    () => (
      <Bestätigungsdialog
        headerText={headerText}
        bodyText={bodyText}
        istOffen={istOffen}
        beiBestätigungKlick={beiBestätigungKlick}
        beiAbbrechenKlick={() => setIsOpen(false)}
        BestätigungsButtonText={BestätigungsButtonText}
      />
    ),
    [ist geöffnet]
  );

  zurückkehren {
    Dialog,
    beim Öffnen,
  };
}

Sie können die Hook-Komponente wie folgt verwenden:

importiere React von „react“;
importiere { useConfirmationDialog } von './useConfirmationDialog'

Funktion Client() {
  const { Dialog, beim Öffnen } = useConfirmationDialog({
    headerText: "Diesen Datensatz löschen?",
    Textkörper:
      "Möchten Sie diesen Datensatz wirklich löschen? Dies kann nicht rückgängig gemacht werden.",
    confirmationButtonText: "Löschen",
    bei Klick bestätigen: handleLöschenBestätigen,
  });

  Funktion handleDeleteConfirm() {
    //TODO: löschen
  }

  const handleDeleteClick = () => {
    beim Öffnen();
  };

  zurückkehren (
    <div>
      <Dialog />
      <button onClick={handleDeleteClick} />
    </div>
  );
}

Standard-Client exportieren;

Wenn Sie Komponenten auf diese Weise extrahieren, müssen Sie nicht viel Boilerplate-Code für die Statusverwaltung schreiben. Wenn Sie mehr über React-Hooks erfahren möchten, lesen Sie meinen Beitrag.

Komponententrennung

In den folgenden drei Tipps geht es um das clevere Aufteilen von Bauteilen. Meiner Erfahrung nach ist die einfachste Methode, Ihr Projekt überschaubar zu halten, wenn Sie die Komponenten einfach halten.

Verwenden eines Wrappers

Wenn Sie Schwierigkeiten haben, eine komplexe Komponente aufzuschlüsseln, sehen Sie sich die Funktionalität an, die jedes Element Ihrer Komponente bietet. Einige Elemente bieten einzigartige Funktionen, wie etwa Drag & Drop.

Hier ist ein Beispiel für eine Komponente, die react-beautiful-dnd zur Implementierung von Drag & Drop verwendet:

React von „react“ importieren
importiere { DragDropContext, Droppable } von „react-beautiful-dnd“;
Export-Standardfunktion DraggableSample() {
  Funktion handleDragStart(Ergebnis) { 
    console.log({ Ergebnis });
  }
  Funktion handleDragUpdate({ Ziel }) { 
    console.log({ Ziel });
  }
  const handleDragEnd = ({ Quelle, Ziel }) => { 
    console.log({ Quelle, Ziel });
  };
  zurückkehren (
    <div>
      <DragDropContext
        onDragEnd={handleDragEnd}
        beiDragStart={handleDragStart}
        beiDragUpdate={handleDragUpdate}
      >
        <Abwerfbar 
          droppableId="abwerfbar"
          Richtung="horizontal"
        >
          {(bereitgestellt) => (
            <div {...provided.droppableProps} ref={provided.innerRef}> 
              {columns.map((Spalte, Index) => {
                zurückkehren (
                  <Spaltenkomponente
                    Schlüssel={index}
                    Spalte={Spalte}
                  />
                );
              })}
            </div>
          )}
        </Abwerfbar>
      </DragDropContext>
    </div>
  )
}

Schauen Sie sich nun die Komponente an, nachdem wir die gesamte Drag-Logik in den Wrapper verschoben haben:

React von „react“ importieren
Export-Standardfunktion DraggableSample() {
  zurückkehren (
    <div>
      <DragWrapper> 
      {columns.map((Spalte, Index) => { 
        zurückkehren (
          <ColumnComponent Schlüssel={index} Spalte={Spalte}/>
        );
      })}
      </DragWrapper>
    </div>
  )
}

Hier ist der Code für den Wrapper:

React von „react“ importieren
importiere { DragDropContext, Droppable } von „react-beautiful-dnd“;
Export-Standardfunktion DragWrapper({children}) {
  Funktion handleDragStart(Ergebnis) { 
    console.log({ Ergebnis });
  }
  Funktion handleDragUpdate({ Ziel }) { 
    console.log({ Ziel });
  }
  const handleDragEnd = ({ Quelle, Ziel }) => { 
    console.log({ Quelle, Ziel });
  };
  zurückkehren (
    <DragDropContext 
      onDragEnd={handleDragEnd}
      beiDragStart={handleDragStart} 
      beiDragUpdate={handleDragUpdate}
    >
      <Droppable droppableId="abwerfbar" Richtung="horizontal"> 
        {(bereitgestellt) => (
          <div {...provided.droppableProps} ref={provided.innerRef}> 
            {Kinder}
          </div>
        )}
      </Abwerfbar>
    </DragDropContext>
  )
}

Daher ist es intuitiver, die Funktion der Komponente auf einer höheren Ebene zu erkennen. Die gesamte Funktionalität zum Ziehen befindet sich im Wrapper, was das Verständnis des Codes erleichtert.

Trennung der Belange

Dies ist meine bevorzugte Methode zum Zerlegen größerer Komponenten.

Aus der Perspektive von React bedeutet Trennung der Belange die Trennung des Teils einer Komponente, der für das Abrufen und Ändern von Daten zuständig ist, von dem Teil, der ausschließlich für die Anzeige von Elementen zuständig ist.

Diese Trennung der Belange ist der Hauptgrund für die Einführung von Hooks. Sie können benutzerdefinierte Hooks verwenden, um Logik zu kapseln, die mit allen Methoden oder dem globalen Status verbunden ist.

Schauen wir uns beispielsweise die folgende Komponente an:

React von „react“ importieren
importiere { someAPICall } von './API' 
importiere ItemDisplay aus './ItemDisplay'
Exportieren der Standardfunktion SampleComponent() { 
  const [Daten, setzeDaten] = useState([])
  useEffect(() => { 
    someAPICall().then((Ergebnis) => { setData(Ergebnis)})
  }, [])
  Funktion handleDelete() { console.log('Löschen!'); }
  Funktion handleAdd() { console.log('Hinzufügen!'); }
  const handleEdit = () => { console.log('Bearbeiten!'); };
  zurückkehren (
    <div>
      <div>
        {data.map(item => <ItemDisplay item={item} />)} 
      </div>
      <div>
        <button onClick={handleDelete} /> 
        <button onClick={handleAdd} /> 
        <button onClick={handleEdit} /> 
      </div>
    </div>
  )
}

Hier ist die überarbeitete Version, die den durch den benutzerdefinierten Hook aufgeteilten Code verwendet:

React von „react“ importieren
importiere ItemDisplay aus './ItemDisplay'
Exportieren der Standardfunktion SampleComponent() {
  const { data, handleDelete, handleEdit, handleAdd } = useCustomHook()
  zurückkehren (
    <div>
      <div>
        {data.map(item => <ItemDisplay item={item} />)} 
      </div>
      <div>
        <button onClick={handleDelete} /> 
        <button onClick={handleAdd} /> 
        <button onClick={handleEdit} /> 
      </div>
    </div>
  )
}

Hier ist der Code für den Hook selbst:

importiere { someAPICall } von './API'
exportiere const useCustomHook = () => { 
  const [Daten, setzeDaten] = useState([])
  useEffect(() => { 
    someAPICall().then((Ergebnis) => { setData(Ergebnis)})
  }, [])
  Funktion handleDelete() { console.log('Löschen!'); }
  Funktion handleAdd() { console.log('Hinzufügen!'); }
  const handleEdit = () => { console.log('Bearbeiten!'); };
  return { handleBearbeiten, handleHinzufügen, handleLöschen, Daten }
}

Jede Komponente wird als separate Datei verpackt

Normalerweise schreiben die Leute Code wie diesen:

React von „react“ importieren
Export-Standardfunktion SampleComponent({ data }) {
  const ItemDisplay = ({ Name, Datum }) => ( 
    <div>
      <h3>{Name}</h3>
      <p>{Datum}</p>
    </div> 
  )
  zurückkehren (
    <div>
      <div>
        {data.map(item => <ItemDisplay item={item} />)}
      </div>
    </div> 
  )
}

Obwohl nichts falsch daran ist, React-Komponenten auf diese Weise zu schreiben, ist es keine gute Vorgehensweise. Durch das Verschieben der ItemDisplay-Komponente in eine separate Datei können Sie die Kopplung Ihrer Komponente lockern und sie leichter erweitern.

In den meisten Fällen erfordert das Schreiben von sauberem und ordentlichem Code Aufmerksamkeit und die Zeit, sich die Zeit zu nehmen, guten Mustern zu folgen und Anti-Muster zu vermeiden. Wenn Sie sich also die Zeit nehmen, diesen Mustern zu folgen, hilft Ihnen das beim Schreiben sauberer React-Komponenten. Ich finde diese Muster bei meinen Projekten sehr nützlich und ich hoffe, Sie tun das auch!

Oben finden Sie ausführliche Tipps zum Schreiben prägnanter React-Komponenten. Weitere Informationen zu Tipps zum Schreiben von React-Komponenten finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Reagieren Sie auf die Verarbeitung von Fehlergrenzkomponenten
  • Detaillierte Erklärung von react setState
  • React implementiert den Beispielcode der Radiokomponente
  • Beispiel für die Verwendung der setInterval-Funktion in React
  • Andrew Ngs maschinelle Lernübung: SVM Support Vector Machine

<<:  Docker verwendet Dockerfile, um die Node.js-Anwendung zu starten

>>:  MySQL-Join-Abfrage (Left Join, Right Join, Inner Join)

Artikel empfehlen

Detaillierte Erklärung gängiger Befehle in MySQL 8.0+

Aktivieren Sie den Fernzugriff Aktivieren Sie die...

Zusammenfassung der praktischen Erfahrungen zu HTML-Wissenspunkten

1. Das Tabellen-Tag ist Tabelle, tr ist Zeile, td ...

Beispielanalyse der MySQL-Indexabdeckung

Dieser Artikel beschreibt die MySQL-Indexabdeckun...

Beispiel zum Überprüfen der Kapazität einer MySQL-Datenbanktabelle

Dieser Artikel stellt die Befehlsanweisungen zum ...

Vue implementiert den Download von ZIP-Dateien

In diesem Artikelbeispiel wird der spezifische Co...

Was ist SSH-Portweiterleitung? Was nützt das?

Inhaltsverzeichnis Vorwort 1. Lokale Portweiterle...

So installieren Sie Postgres 12 + pgadmin im lokalen Docker (unterstützt Apple M1)

Inhaltsverzeichnis einführen Unterstützt Intel-CP...

So richten Sie die Swap-Partition SWAP in Linux 7.7 ein

Die Swap-Partition des Linux-Systems, also die Sw...

Schreiben Sie mit CSS in drei Schritten einen Coupon für eine Shopping-Card

Heute ist der 618. und alle großen Einkaufszentre...

Detaillierte Erläuterung des automatischen Füllschreibens von CSS3-Flexboxen

In diesem Artikel wird hauptsächlich die Methode ...

Verständnis und Anwendung des Destrukturierungsoperators von JavaScript ES6

Inhaltsverzeichnis Vorwort Die Rolle von Dekonstr...