React.memo - warum wird meine Gleichstellungsfunktion nicht aufgerufen?

8

Ich habe eine übergeordnete Komponente, die eine Sammlung von untergeordneten Elementen basierend auf einem über Requisiten empfangenen Array rendert.

import React from 'react';
import PropTypes from 'prop-types';
import shortid from 'shortid';
import { Content } from 'components-lib';
import Child from '../Child';

const Parent = props => {
  const { items } = props;

  return (
    <Content layout='vflex' padding='s'>
      {items.map(parameter => (
        <Child parameter={parameter} key={shortid.generate()} />
      ))}
    </Content>
  );
};

Parent.propTypes = {
  items: PropTypes.array
};

export default Parent;

Jedes Mal, wenn ein neues itemhinzugefügt wird, werden alle Kinder neu gerendert, und ich versuche dies zu vermeiden. Ich möchte nicht, dass andere Kinder neu gerendert werden. Ich möchte nur das zuletzt hinzugefügte rendern.

Also habe ich React.memo an dem Kind ausprobiert, wo ich es wahrscheinlich anhand der codeEigenschaft oder so vergleichen werde . Das Problem ist, dass die Gleichheitsfunktion niemals aufgerufen wird.

import React from 'react';
import PropTypes from 'prop-types';
import { Content } from 'components-lib';

const areEqual = (prevProps, nextProps) => {
  console.log('passed here') // THIS IS NEVER LOGGED!!
}

const Child = props => {
  const { parameter } = props;
  return <Content>{parameter.code}</Content>;
};

Child.propTypes = {
  parameter: PropTypes.object
};

export default React.memo(Child, areEqual);

Irgendwelche Ideen warum?

Joana Deluca Kleis
quelle
1
Es wird nichts protokolliert, bis die Requisiten geändert werden. Versuchen Sie, die Requisiten Ihrer Eltern zu optimieren.
freundlicher Benutzer
Sie haben einen Fehler beim Importieren von "Import Child from" ../Child "" nicht sicher, ob dies die Ursache ist.
Afia
1
Wenn Sie versuchen, unnötige Renderings Ihrer untergeordneten Komponenten zu verhindern, sollten Sie jedem einen eindeutigen Schlüssel geben. React hat eine sehr heikle Art, mit Schlüsseln umzugehen. Wenn sich ein Schlüssel einer Komponente ändert, wird er von React vollständig neu gerendert. Wenn Sie jedes Mal einen neuen Schlüssel generieren, wird React jedes Mal alles neu rendern, wenn sich die Requisiten im übergeordneten Element ändern.
Konstantin
@konstantin du bist ein Genie !! Ich habe die Schlüsselgenerierung entfernt und es hat wie ein Zauber funktioniert !! : D Die Gleichheit fn wird jetzt aufgerufen und ich könnte den Vergleich machen. Vielen Dank!! Können Sie dies als Antwort hinzufügen, damit ich als die richtige abstimmen kann?
Joana Deluca Kleis
Ich bin froh, dass ich helfen konnte :), werde es jetzt hinzufügen
Konstantin

Antworten:

2

Kurz gesagt, der Grund für dieses Verhalten liegt in der Funktionsweise von React.

React erwartet für jede der Komponenten einen eindeutigen Schlüssel, damit es den Überblick behalten und wissen kann, welcher welcher ist. Durch die Verwendung shortid.generate()eines neuen Werts des Schlüssels wird der Verweis auf die Komponente geändert und React glaubt, dass es sich um eine völlig neue Komponente handelt, die erneut gerendert werden muss.

In Ihrem Fall rendert React bei jeder Änderung der Requisiten im übergeordneten Element alle untergeordneten Elemente, da die Schlüssel für alle untergeordneten Elemente im Vergleich zum vorherigen Rendering unterschiedlich sind.

Bitte verweisen Sie auf diese wunderbare Antwort auf dieses Thema

Hoffe das hilft!

Konstantin
quelle
0

Ich kenne den Rest Ihrer Bibliothek nicht, aber ich habe einige Änderungen vorgenommen und Ihr Code scheint (meistens) zu funktionieren. Vielleicht kann es Ihnen helfen, die Ursache einzugrenzen.

https://codesandbox.io/s/cocky-sun-rid8o

Luh
quelle
Vielen Dank, dass Sie sich Zeit genommen und diese Code-Sandbox erstellt haben. Ich schätze es! Mein Fall ist etwas anders, Sie ändern explizit die Eigenschaft, wenn Sie auf die Schaltfläche klicken, und das löst das fn aus. In meinem Fall füge ich dem Array der Eltern lediglich ein neues Element hinzu, erstelle jedes Mal ein neues untergeordnetes Element und erwarte, dass das fn ausgelöst wird. Ich habe gerade herausgefunden, dass das Problem der Schlüssel war, den ich zufällig generiert habe.
Joana Deluca Kleis