Detaillierte Erklärung zur Verwendung von React.cloneElement

Detaillierte Erklärung zur Verwendung von React.cloneElement

Da wir die Wartung einiger Projekte selbst übernehmen müssen, wurde der Technologie-Stack des Teams kürzlich von Vue auf React umgestellt. Als React-Neuling und weil ich immer gerne neue Dinge durch Quellcode lerne, habe ich mich entschieden, die Verwendung von React durch das Lesen des Quellcodes des berühmten Projekts antd zu erlernen.

Beim Lesen des Quellcodes stellte ich fest, dass viele Komponenten die API React.cloneElement verwendeten. Obwohl ich anhand des Namens erraten konnte, was es tat, kannte ich seine spezifische Funktion nicht. Dann las ich die offizielle Dokumentation, in der die Funktion klar beschrieben wurde, uns jedoch nicht gesagt wurde, in welchen Szenarien wir es verwenden müssen. Daher habe ich einige Verwendungsszenarien basierend auf der Beschreibung im Dokument zusammengefasst, mit der Verwendung des Quellcodes kombiniert und mich an Google und Stackoverflow orientiert.

Die Rolle von cloneElement

React.cloneElement(
 Element,
 [Requisiten],
 [...Kinder]
)

Schauen Sie sich zunächst die offizielle Dokumentation dieser API an:

Klonen und geben Sie ein neues React-Element zurück, wobei Sie das Element als Ausgangspunkt verwenden. Das resultierende Element enthält die Eigenschaften des ursprünglichen Elements, wobei die neuen Eigenschaften oberflächlich integriert sind. Neue untergeordnete Elemente ersetzen vorhandene untergeordnete Elemente. Schlüssel und Referenz des ursprünglichen Elements bleiben erhalten.

Um zusammenzufassen:

  1. Klonen Sie das Originalelement und geben Sie ein neues React-Element zurück.
  2. Behalten Sie die Requisiten des Originalelements bei, fügen Sie neue Requisiten hinzu und führen Sie die beiden oberflächlich zusammen.
  3. Schlüssel und Referenz bleiben erhalten, da es sich auch um Eigenschaften handelt und sie daher auch geändert werden können.
  4. Laut dem Quellcode von React können wir ab dem dritten Parameter beliebig viele Kindelemente definieren. Wenn neue Kinder definiert werden, werden die ursprünglichen Kinder ersetzt.

Anwendungsszenarien

Gemäß der obigen Definition können wir diese API nach Bedarf in verschiedenen Szenarien verwenden.

Neue Requisiten hinzufügen

Wenn wir eine gemeinsame Komponente erstellen, möchten wir jedem untergeordneten Element gemäß der internen Logik unterschiedliche Klassennamen hinzufügen. Zu diesem Zeitpunkt können wir den className ändern:

Angenommen, wir haben eine Timeline-Komponente, mit der wir bei Bedarf mehrere TimelineItem definieren können. Intern möchten wir dem letzten TimelineItem eine Klasse timeline-item-last hinzufügen, um einen Spezialeffekt zu rendern. Zu diesem Zeitpunkt können wir Folgendes tun:

const MyTimeline = () => {
 zurückkehren (
  <Zeitleiste>
   <TimelineItem>01.06.2020</TimelineItem>
   <TimelineItem>08.06.2020</TimelineItem>
   <TimelineItem>05.07.2020</TimelineItem>
  </Zeitleiste>
 )
}

// Innerhalb der Zeitleiste könnte die Logik wie folgt aussehen: „import class from 'classnames';“
const Timeline = Requisiten => {
 // ...
 // ...
 const itemCount = React.children.count(props.children);
 const items = React.children.map(props.children, (item, index) => {
  returniere React.cloneElement(item, {
   Klassenname: Klasse ([
    Artikel.Eigenschaften.Klassenname,
    "Zeitleistenelement",
    Index === Anzahl – 1? 'letztes Timeline-Element': ''
   ])
  })
 }
 return <div className={'timeline'}>{ Elemente }</div>
}

Zusätzlich zum Hinzufügen von className können Sie Unterkomponenten auch dynamisch weitere Props-Informationen hinzufügen. Switch von react-router fügt passenden Unterkomponenten location und computedMatch Informationen hinzu:

Klasse Switch erweitert React.Component {
 rendern() {
  zurückkehren (
   <RouterContext.Verbraucher>
    {Kontext => {
     invariant(context, "Sie sollten <Switch> nicht außerhalb eines <Routers> verwenden");

     const Standort = this.props.location || Kontext.Standort;

     Lass das Element übereinstimmen;

     // Wir verwenden React.Children.forEach anstelle von React.Children.toArray().find()
     // hier, weil toArray Schlüssel zu allen untergeordneten Elementen hinzufügt und wir nicht wollen
     // um ein Unmounten/Remounten für zwei <Route>s auszulösen, die dasselbe rendern
     // Komponente unter verschiedenen URLs.
     React.Children.fürEach(this.props.children, Kind => {
      wenn (match == null und React.isValidElement(child)) {
       Element = Kind;

       const Pfad = Kind.props.Pfad || Kind.props.von;

       Übereinstimmung = Pfad
        ? matchPath(Standort.Pfadname, { ...child.props, Pfad })
        : Kontext.Übereinstimmung;
      }
     });

     Revanche
      React.cloneElement(Element, {Standort, berechnete Übereinstimmung: Übereinstimmung})
      : null;
    }}
   </RouterContext.Consumer>
  );
 }
}

Ereignisse, die Requisiten verändern

Angenommen, wir haben eine Tab-Komponente, die mehrere TabPane Unterkomponenten enthält. Wir möchten das onClick -Ereignis der Registerkarte auslösen, wenn auf jede TabPane Unterkomponente geklickt wird. Der Benutzer kann für jedes TabPane ein unabhängiges onClick -Ereignis definieren. In diesem Fall müssen wir das onClick -Ereignis der Unterkomponente ändern:

const Tab = props => {
 const { beim Klicken } = Requisiten;
 const tabPanes = React.children.map(props.children, (tabPane, index) => {
  const paneClick = () => {
   beiKlick und beiKlick(Index);
   tabPane.props?.onClick();
  }
  returniere React.cloneElement(tabPane, {
    bei Klick: Fensterklick,
  })
 })
 return <div>{ Tabulatortasten }</div>
}

Benutzerdefinierter Stil

Beim Erstellen einer Komponente namens FollowMouse können Benutzer die Inhaltskomponente Content definieren. Wenn sich die Maus bewegt, wird die Position von Content automatisch entsprechend der Größe des Inhalts berechnet, um ein Überlaufen des Bildschirms zu vermeiden. Zu diesem Zeitpunkt können wir cloneElement verwenden, um seinen Stil dynamisch zu ändern.

// Der Einfachheit halber werden Mausereignisse hier weggelassen.
const FollowMouse = props => {
 const { Inhalt } = Requisiten;
 const customContent = React.isValidElement ? Inhalt : <span>{ Inhalt }</span>
 const getOffset = () => {
  zurückkehren {
   Position: 'absolut',
   Spitze: ...,
   links: ...,
  }
 }
 const renderContent = React.cloneElement(custonContent, {
  Stil: {
   …getOffset()
  }
 })
 return <div>{ renderContent() }</div>
}

Schlüssel hinzufügen

Wenn wir eine Liste von Elementen erstellen, können wir jedem Knoten über cloneElement einen Schlüssel hinzufügen.

const ComponentButton = Eigenschaften => {
 const { addonAfter, untergeordnete Elemente } = Requisiten;
 const button = <button key='button'>{ untergeordnete Elemente }</button>
 const-Liste = [Schaltfläche, Add-onAfter? React.cloneElement(AddonAfter, {Schlüssel: 'Button-Addon'}: null)
 zurück <div>{ Liste } <div>
}

Zusammenfassen

Bei der Entwicklung komplexer Komponenten fügen wir den untergeordneten Komponenten häufig je nach Bedarf verschiedene Funktionen oder Anzeigeeffekte hinzu. Das react Element selbst ist ein unveränderliches Objekt. props.children sind eigentlich nicht children selbst, sondern nur der Deskriptor der children . Wir können keine seiner Eigenschaften ändern, sondern nur seinen Inhalt lesen. Daher können wir React.cloneElement seine Elemente kopieren und neue Props ändern oder hinzufügen, um unsere Ziele zu erreichen.

Dank des leistungsstarken Kombinationsmodus von React ist dies natürlich nicht auf props.children beschränkt. Unabhängig davon, ob props.left oder props.right oder andere übergebene props vorhanden sind, können wir dieses React.cloneElement verwenden, um damit zu arbeiten, solange es sich um ein gültiges React-Element handelt.

Oben finden Sie den detaillierten Inhalt der ausführlichen Erläuterung zur Verwendung von React.cloneElement. Weitere Informationen zur Verwendung von React.cloneElement finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Detaillierte Verwendung von React.Children
  • Anwendungsbeispiele für React Hooks
  • Tiefgreifendes Verständnis der Kernprinzipien von React Native (Bridge of React Native)
  • React+Koa-Beispiel zur Implementierung des Datei-Uploads
  • Beispielcode für die Entwicklung einer H5-Formularseite basierend auf React-Hooks und der Konfiguration der Zarm-Komponentenbibliothek
  • Das Umschalten zwischen React-Antd-Tabs führt zu wiederholter Aktualisierung von Unterkomponenten
  • ReactJs-Grundlagen-Tutorial - Essential Edition
  • ReactRouter-Implementierung

<<:  MySQL 5.5.56-Version (Installation von Binärpaketen) benutzerdefinierter Installationspfad-Schrittdatensatz

>>:  Detaillierte Erklärung der binären und varbinären Datentypen in MySQL

Artikel empfehlen

Zusammenfassung der sieben MySQL JOIN-Typen

Bevor wir beginnen, erstellen wir zwei Tabellen, ...

So verwenden Sie nginx zum Konfigurieren des Zugriffs auf wgcloud

Die Nginx-Konfiguration ist wie folgt: Wie http:/...

Detailliertes Beispiel des MySQL InnoDB-Sperrmechanismus

1. InnoDB-Sperrmechanismus Die InnoDB-Speicher-En...

Zusammenfassung der bei der Arbeit häufig verwendeten Linux-Befehle

Verwenden Sie bei der Arbeit mehr Open-Source-Too...

JavaScript zum Implementieren einer dynamischen Digitaluhr

In diesem Artikel finden Sie den spezifischen Cod...

Vue-cli erstellt ein Projekt und analysiert die Projektstruktur

Inhaltsverzeichnis 1. Geben Sie ein Verzeichnis e...

Einführung in die Verwendung sowie Vor- und Nachteile von MySQL-Triggern

Inhaltsverzeichnis Vorwort 1. Trigger-Übersicht 2...

Automatische Sicherung der MySQL-Datenbank per Shell-Skript

Automatische Sicherung der MySQL-Datenbank per Sh...

Zusammenfassung der MySQL-Zeichensätze

Inhaltsverzeichnis Zeichensatz Vergleichsregeln V...

Detailliertes Installationstutorial für mysql-8.0.11-winx64.zip

Laden Sie das ZIP-Installationspaket herunter: Do...

Detaillierte Erklärung der Kernfunktionen und der Ereignisbehandlung von jQuery

Inhaltsverzeichnis Ereignis Seite wird geladen Ve...

Analyse von MySQL-Beispielen für doppelte und redundante Indizes

In diesem Artikel werden MySQL-Duplikatsindizes u...

Einige Datenverarbeitungsmethoden, die häufig in JS verwendet werden können

Inhaltsverzeichnis DOM-Verarbeitung Arrays Verfah...

Detaillierte Erklärung der Funktion und Verwendung der KeepAlive-Komponente in Vue

Vorwort Während des Vorstellungsgesprächs erwähne...