2017-06-14 4 views
3

Ich könnte etwas fehlen, aber ich habe eine Komponente wie dieseReact.PureComponent Umsetzung shouldComponentUpdate nicht

export default MyComponent extends React.PureComponent { 
    // ... 
} 

Wenn MyComponent Teil eines anderen Komponenten machen Methode ist, MyComponent jedes Mal wieder macht die Eltern macht, auch wenn die Requisiten/der Zustand unverändert sind. So scheint es, dass die Änderung von React.Component zu React.PureComponent die Komponente nicht "rein" gemacht hat.

Ich versuchte

console.info(this.shouldComponentUpdate) 

in der eine der Komponenten Methoden hinzufügen, und sie sagt, es ist nicht definiert. Ist nicht React.PureComponent soll eine flache vergleichen shouldComponentUpdate Methode hinzufügen?

mit React 15.5.4 und Dies ist nun geschehen 15.6.0

Antwort

1

A PureComponent nicht die shouldComponentUpdate direkt erklären. Sie können es nicht mit this.shouldComponentUpdate besuchen. Im Quellcode Reagieren gibt es eine shouldUpdate Variable:

(der Quellcode unter vereinfacht)

// default is true 
var shouldUpdate = true; 

if (inst.shouldComponentUpdate) { 
    shouldUpdate = inst.shouldComponentUpdate(
    nextProps, 
    nextState, 
    nextContext, 
); 
} else { 
    // if it's a PureComponent 
    if (this._compositeType === ReactCompositeComponentTypes.PureClass) { 
    shouldUpdate = 
     !shallowEqual(prevProps, nextProps) || 
     !shallowEqual(inst.state, nextState); 
    } 
} 

// ... 

if (shouldUpdate) { 
    // re-render .. 
} 

Da es nur flach gleich ist, wird der Code unten gibt false zurück, und Sie erhalten eine Re-Render:

const propA = { foo: 'bar' } 
const nextPropA = { foo: 'bar' } 

shallowEqual(propA, nextPropA) // false 

Verwenden Sie also Objekte und Arrays sorgfältig. Um sicherzustellen, dass PureComponent Werke zu beweisen, finden Sie in diesem Beispiel (v15.6): https://codepen.io/CodinCat/pen/eRdzXM?editors=1010

Durch Klicken auf die Schaltfläche wird nicht auslösen Foo ‚s machen:

enter image description here

Hier ist ein weiteres Beispiel dafür, dass PureComponent möglicherweise nicht für Sie: https://codepen.io/CodinCat/pen/QgKKLg?editors=1010

Der einzige Unterschied ist <Foo someProp={{ foo: 'bar' }} />

Weil { foo: 'bar' } !== { foo: 'bar' }, reagieren Rendern jedes Mal neu. Also Inline Objekte und Arrays in Requisiten direkt schreiben ist keine gute Praxis. Ein häufiger Fehler ist das Schreiben Inline-Stil:

<Foo style={{ color: 'pink' }} /> 

In diesem Fall Foo wird erneut rendern immer, auch wenn es ein PureComponent ist. Wenn Sie dieses Problem konfrontiert sind, können Sie einfach extrahieren und speichern Sie das Objekt irgendwo, zum Beispiel:

const someProp = { foo: 'bar' } 

<Foo someProp={someProp} /> 

Seit someProp === someProp, die PureComponent arbeitet.

+0

Es sieht so aus, als ob Objekte als Props übergeben werden. Ich verstehe das Vergleichsproblem, aber fühle mich weg von obj/arr Requisiten ist nicht die beste Lösung. Dies liegt daran, dass Datenstrukturen in der App in Kombination mit wiederverwendbaren Komponenten häufig dazu führen, dass Listen von Entitäten weitergegeben werden und dann eine Entität zum Rendern an eine Unterkomponente gesendet wird, oft zusammen mit einigen anderen Requisiten.Wenn ich alle Entity-Data-Requisiten mit anderen Requisiten (wie Verhaltensrequisiten) mische, werden die Requisiten-Definitionen zu einem Chaos. Ich denke, das bedeutet, dass ich meine eigene somethomComponentUpdate erstellen muss, also kann ich React.PureComponent nicht verwenden. – henit

+0

Ich meinte, Objekte und Arrays inline zu schreiben. Aktualisiert die Antwort, um es klarer zu machen – CodinCat

+0

Versuchen Sie nicht, etwas wie '' dann PureComponent sollte funktionieren – CodinCat