React: DOM in ComponentDidUpdate manipulieren

Erstellt am 23. Sept. 2016  ·  3Kommentare  ·  Quelle: facebook/react

Hallo, dies ist eher eine Frage, ich möchte eine Diskussion über die DOM-Manipulation in componentDidUpdate eröffnen.

Ich erstelle ein React-Plugin. Es muss einige DOM-Berechnungen durchführen, da CSS nicht leistungsstark genug ist, um alles abzudecken, was dieses Plugin tun muss. Das Problem ist, dass ich einige CSS-Eigenschaften abhängig vom Rückgabewert von getBoundingClientRect() eines anderen DOM-Elements anpassen muss, das von derselben Komponente gerendert wird .

Technisch haben wir also 3 Möglichkeiten:

1) Berechne getBoundingClientRect in componentDidUpdate und rufe setState mit berechneten Werten auf. Ich habe Angst vor der Endlosschleife, die in bestimmten Fällen passieren könnte, also würde ich mich nicht für diese entscheiden.

2) Machen Sie es wie in 1) und spielen Sie ein bisschen mit shouldComponentUpdate , aber das scheint sehr komplex und nicht lesbar zu sein. Es tauchen viele Fragen auf, die vom jeweiligen Anwendungsfall abhängig sind.

3) Aktualisieren Sie DOM von ComponentDidUpdate. Dies ist die Lösung, für die ich mich entschieden habe, sie funktioniert, sie ist einfach, stabil und funktioniert wie beabsichtigt. Ich habe jedoch das Gefühl, dass ich am Rande bin, also wollte ich noch einmal überprüfen, ob dies eine OK-Methode ist. Ist es in Ordnung, DOM in componentDidUpdate zu manipulieren? Es wird jedes Mal aufgerufen, wenn render fertig ist, und ich bin damit einverstanden, meine Änderungen wegzuwerfen, denn für die nächsten render werde ich DOM wieder modifizieren.

Hier ist ein Teil des Codes

componentDidMount() {
  this.recalculateIndent();
}

componentDidUpdate() {
  this.recalculateIndent();
}

recalculateIndent() {
  // calculate indent based on getBoundingClientRect of some DOM reference
  this.textareaRef.style.textIndent = `${indent}px`;
}

render() {
   return (
   ...
   <textarea ref={ref => this.textareaRef = ref}/>
   ...
   );
}

Hilfreichster Kommentar

@jvorcak mit componentDidUpdate ist der richtige Ort, um das DOM nach einem Rendern manuell zu bearbeiten. Laut den Dokumenten:

Nutzen Sie dies als Gelegenheit, das DOM zu bearbeiten, wenn die Komponente aktualisiert wurde.

Außerdem versuchen wir, den Issue Tracker ausschließlich für Funktionsanfragen und Fehlerberichte zu verwenden. Fragen zur Verwendung sollten an andere Stellen gerichtet werden, z. B.

Alle 3 Kommentare

Jede Lösung (Komponentenlebenszyklusmethode) ist für eine konkrete Situation geeignet, aber die DOM-Manipulation ist falsch. Verwenden Sie den Zustand und rendern Sie die Komponente erneut. Beispiel für meinen letzten Anwendungsfall "Fixed Header für Tabelle + virtuelles Scrollen für Tabellenkörper", ich hoffe, dies hilft Ihnen, den richtigen Ablauf zu verstehen.

  1. Komponentenkonstruktor: Anfangszustandswert: bodyHeight = 0 (oder null, wie Sie möchten).
  2. Erstes Rendern, rendert den Tabellenkopf, aber den Tabellenkörper (0 Zeilen).
  3. ComponentDidMount - Header- und Container-DOM-Höhe lesen (+ einige Berechnungen...) und setState für bodyHeight (erneut rendern).
  4. Zweites Rendern, bodyHeight !== 0, Tabellenkörper wird gerendert. Jetzt ist der Höhenparameter bekannt ( ich kann ihn mit "style" -Komponentenprop statt DOM-Manipulation einstellen ), ich kann Komponenten für Zeilen hinzufügen.
  5. Zusätzlicher Event-Listener für "resize" (Dokument-/Browser-Größenänderung), in componentDidMount hinzufügen, in componentWillUnmount entfernen. Im Event-Handler mache ich dasselbe wie in componentDidMount - lese neue DOM-Höhenwerte und setState.
  6. Es gibt keine DOM-Manipulation von Hand, Reagieren erledigt den Job.

@jvorcak mit componentDidUpdate ist der richtige Ort, um das DOM nach einem Rendern manuell zu bearbeiten. Laut den Dokumenten:

Nutzen Sie dies als Gelegenheit, das DOM zu bearbeiten, wenn die Komponente aktualisiert wurde.

Außerdem versuchen wir, den Issue Tracker ausschließlich für Funktionsanfragen und Fehlerberichte zu verwenden. Fragen zur Verwendung sollten an andere Stellen gerichtet werden, z. B.

Was ist, wenn Sie eine Komponente aktualisieren möchten, nachdem Sie etwas in einer anderen geändert haben?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen