Ein kurzer Vergleich von Props in React

Ein kurzer Vergleich von Props in React

Als ich letzte Woche zu einem Vorstellungsgespräch ging, fragte mich der Interviewer, wie man props in PureComponent vergleicht. Das Konzept hatte ich bereits im Kopf, und das Erste, was mir herausplatzte, war „oberflächlicher Vergleich“. Dann fragte mich der Interviewer, wie ich den oberflächlichen Vergleich durchführe, aber ich konnte nicht antworten.

Nutzen Sie das Wochenende, um zu sehen, wie es im Quellcode implementiert ist.

Props-Vergleich von Klassenkomponenten

Ob die Klassenkomponente aktualisiert werden muss, muss die Methode shouldComponentUpdate implementieren. Wenn sie PureComponent erbt, gibt es im Allgemeinen eine standardmäßige oberflächliche Vergleichsimplementierung.

// ReactBaseClasses.js
Funktion ComponentDummy() {}
ComponentDummy.prototype = Komponente.prototype;

/**
 * Komfortkomponente mit standardmäßiger oberflächlicher Gleichheitsprüfung für sCU.
 */
Funktion PureComponent(Eigenschaften, Kontext, Updater) {
  this.props = Requisiten;
  dieser.Kontext = Kontext;
  // Wenn eine Komponente String-Referenzen hat, weisen wir später ein anderes Objekt zu.
  this.refs = leeresObjekt;
  this.updater = Updater || ReactNoopUpdateQueue;
}

const pureComponentPrototype = (PureComponent.prototype = neuer ComponentDummy());
pureComponentPrototype.Konstruktor = PureComponent;
// Vermeiden Sie einen zusätzlichen Prototypsprung für diese Methoden.
Objekt.assign(pureComponentPrototype, Component.prototype);
pureComponentPrototype.isPureReactComponent = true;

Die Implementierung von PureComponent ist wie oben beschrieben. Ich dachte immer, dass die Methode shouldComponentUpdate bei der Deklaration standardmäßig implementiert würde, aber tatsächlich gibt es keine Standardmethode.

Als nächstes schauen wir uns den Aufruf shouldComponentUpdate an.

// ReactFiberClassComponent.js
Funktion checkShouldComponentUpdate(
  in Arbeit,
  ctor,
  alte Requisiten,
  neue Requisiten,
  alter Staat,
  neuerStatus,
  nächsterKontext,
) {
  const-Instanz = workInProgress.stateNode;
  // Wenn die Instanz shouldComponentUpdate implementiert, gib das Ergebnis des Aufrufs zurück, if (typeof instance.shouldComponentUpdate === 'function') {
    const shouldUpdate = Instanz.shouldComponentUpdate(
      neue Requisiten,
      neuerStatus,
      nächsterKontext,
    );
    sollteUpdate zurückgeben;
  }

  // Oberflächlicher Vergleich bei Verwendung von PureReactComponent if (ctor.prototype && ctor.prototype.isPureReactComponent) {
    zurückkehren (
      !shallowEqual(alteProps, neueProps) || !shallowEqual(alterZustand, neuerZustand)
    );
  }

  gibt true zurück;
}

Es ist ersichtlich, dass für PureReactComponent tatsächlich keine separate shouldComponentUpdate-Methode geschrieben wurde, aber während des Vergleichs wird das Ergebnis eines oberflächlichen Vergleichs zurückgegeben.

Die Antworten auf die oberflächlichen Vergleiche liegen alle in der Methode shallowEqual.

flachGleicher flacher Vergleich

// flachEqual.js
Funktion flachEqual(ObjektA: gemischt, ObjektB: gemischt): Boolesch {
  // Das gleiche Objekt gibt „true“ zurück
  wenn (Objekt.ist(ObjektA, ObjektB)) {
    gibt true zurück;
  }

  // Wenn es kein Objekt oder null ist, gib false zurück.
  Wenn (
    Typ von ObjektA !== 'Objekt' ||
    objA === null ||
    Typ von ObjektB !== 'Objekt' ||
    objB === null
  ) {
    gibt false zurück;
  }

  const keysA = Objekt.keys(objA);
  const keysB = Objekt.keys(objB);

  // Wenn die Anzahl der Schlüssel unterschiedlich ist, gib false zurück
  wenn (SchlüsselA.Länge !== SchlüsselB.Länge) {
    gibt false zurück;
  }

  // Wenn die entsprechenden Schlüsselwerte nicht gleich sind, geben Sie false zurück
  für (lass i = 0; i < SchlüsselA.Länge; i++) {
    Wenn (
      !hasOwnProperty.call(ObjektB, SchlüsselA[i]) ||
      !Objekt.ist(ObjektA[SchlüsselA[i]], ObjektB[SchlüsselA[i]])
    ) {
      gibt false zurück;
    }
  }

  gibt true zurück;
}

Das Prinzip der ShallowEqual-Methode ist sehr einfach

  1. Stellen Sie zunächst fest, ob es sich bei beiden um dasselbe Objekt handelt.
  2. Bestimmen Sie, ob der Wert beider kein Objekt oder null ist.
  3. Vergleichen Sie die Längen der beiden Schlüssel.
  4. Bestimmen Sie, ob die den beiden Schlüsseln entsprechenden Werte identisch sind.

Es stellt sich heraus, dass das Prinzip ein so einfacher Vergleich ist: Wenn ich während des Vorstellungsgesprächs den Quellcode aufsagen kann, bekomme ich dann ein höheres Gehalt?

Ein kurzer Vergleich der Funktionskomponenten

Die oberflächliche Vergleichsmethode von Funktionskomponenten wird mit der React.memo-Methode implementiert.

// ReactMemo.js
Exportfunktion Memo<Props>(
  Typ: React$ElementType,
  vergleichen?: (oldProps: Props, newProps: Props) => boolean,
) {
  const elementType = {
    $$Typ von: REACT_MEMO_TYPE,
    Typ,
    vergleichen: vergleichen === undefiniert? null: vergleichen,
  };
  Elementtyp zurückgeben;
}

Die React.memo-Methode unterstützt auch die Übergabe einer Vergleichsfunktion als zweiten Parameter.

Die interne Verarbeitung erstellt tatsächlich manuell ein ReactElement mit $$typeof als REACT_MEMO_TYPE, um die nachfolgende Typbeurteilung zu erleichtern.

Die Erstellung der React.memo-Komponente ist etwas komplizierter. Da eine zweite benutzerdefinierte Vergleichsfunktion übergeben werden kann, wird sie intern tatsächlich als zwei Arten von Fiber-Knoten definiert.

  • Die Komponente ohne die übergebene Vergleichsfunktion ist SimpleMemoComponent.
  • Diejenige, die die benutzerdefinierte Vergleichsfunktion übergibt, ist MemoComponent.

Der eigentliche Vergleich der Props ist jedoch derselbe, und zum Vergleich wird standardmäßig die Methode shallowEqual aufgerufen.

updateSimpleMemoComponent

Wenn (
  flachEqual(vorherigeProps, nächsteProps) &&
  aktuell.ref === workInProgress.ref
) {
	// ...
}

updateMemoComponent

// ...
lass vergleichen = Komponente.vergleichen;
vergleichen = vergleichen !== null? vergleichen: flachEqual;
wenn (vergleiche(vorherigeProps, nächsteProps) und aktuell.ref === workInProgress.ref) {
  Rückgabewert für bailoutOnAlreadyFinishedWork(aktuell, workInProgress, renderLanes);
}
// ... 

Warum es in zwei Komponenten aufgeteilt ist, verstehe ich nicht ganz. Es hängt wahrscheinlich mit der Update-Planung zusammen.

Der Fiber-Knoten von SimpleMemoComponent entspricht tatsächlich einer Funktionskomponente mit geändertem Namen. Der Prozess geht direkt zur Funktionskomponente, während MemoComponent mit einer Hülle bedeckt ist. Sie müssen zuerst die Hülle abziehen, um einen untergeordneten Fiber-Knoten zu generieren, und dann basierend auf der Beurteilung des untergeordneten Fiber-Knotens zur Funktionskomponente gehen.

Das Obige ist eine kurze Analyse von Props.

Oben finden Sie den detaillierten Inhalt des oberflächlichen Vergleichs von Props in React. Weitere Informationen zum oberflächlichen Vergleich von Props in React finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Kontext und Eigenschaften von React erklärt
  • Detaillierte Erläuterung der Verwendung von Requisiten in den drei Hauptattributen von React
  • Sprechen Sie über das Render Props-Muster in React
  • Detaillierte Erläuterung der Vererbung, Instanziierung und des React-Super-(Props-)Prinzips der ES6-Klassenkette
  • Ein Artikel, der Ihnen hilft, die Prinzipien von React Props zu verstehen

<<:  Detaillierte Schritte zur vollständigen Deinstallation von MySQL 5.7

>>:  Beispiel für die Konfiguration von Nginx im CentOS-Server

Artikel empfehlen

Detaillierte Erläuterung der Einführung in die JavaScript-Funktion

Inhaltsverzeichnis Funktionseinführung Funktion E...

Delegieren von Berechtigungen in Linux mit Sudo

Einführung in die Sudo-Autoritätsdelegierung su-S...

Ursachenanalyse und Lösung des E/A-Fehlers beim Löschen einer MySQL-Tabelle

Problemphänomen Ich habe kürzlich Sysbench verwen...

Einfaches Beispiel für die Verschönerung von HTML-Kontrollkästchen und -Radios

Einfaches Beispiel für die Verschönerung von HTML...

5 MySQL-GUI-Tools, die Ihnen bei der Datenbankverwaltung empfohlen werden

Es gibt viele Datenbankverwaltungstools für MySQL...

Lösung für den erfolgreichen Start von MySQL, aber ohne Überwachung des Ports

Problembeschreibung MySQL wurde erfolgreich gesta...

So führen Sie den sudo-Befehl aus, ohne in Linux ein Passwort einzugeben

Mit dem Befehl „sudo“ kann ein vertrauenswürdiger...

Zusammenfassung mehrerer Situationen, in denen MySQL-Indizes fehlschlagen

1. Indizes speichern keine Nullwerte Genauer gesa...