2016-04-13 5 views
5

Ich arbeite an einer Drag-and-Drop-Implementierung (von Grund auf neu, keine DND-Bibliothek verwenden) und wollte die Anzahl der unnötigen Updates beim Ziehen beschränken.Reagieren: Beste Möglichkeit, sich selbst zu aktualisieren, aber verhindern, dass Kinder aktualisieren?

Ziehen des „klonen“ (die in der Regel eine Kopie des Original-Element ist, sondern kann ein beliebiger Platzhalter sein) erzielt wird, indem ein Zustand auf einer Behälterkomponente Aktualisierung (der „Clonetainer“) und unter Verwendung dass eine Transformation anzuwenden . Es macht jedoch keinen Sinn, den gesamten Teilbaum während einer Bewegung zu aktualisieren, da nur die Koordinaten des Containers geändert werden.

Hier ist meine Lösung, dass:

const ClonetainerRenderShield = React.createClass({ 
    shouldComponentUpdate: function (newProps) { 
     return newProps.shouldUpdate; 
    }, 
    render: function() { 
     return this.props.children; // Simple pass-through 
    } 
}); 

const Clonetainer = React.createClass({ 
    componentWillReceiveProps: function (newProps) { 
     // OR in any further properties that may indicate a move, versus a child update 
     this.isMoveEvent = this.props.offset !== newProps.offset; 
    }, 
    render: function() { 
     const style = { transform: `translate(${this.props.offset.left}px,${this.props.offset.top}px)` }; 
     return <div className="clonetainer-div" style={style}> 
      <ClonetainerRenderShield shouldUpdate={ !this.isMoveEvent }> 
       { this.props.children } 
      </ClonetainerRenderShield> 
     </div>; 
    } 
}); 

(Ich werde nicht in die Details auf dem Rest des DND Systems gehen, es sei denn, dass die Maus-Ereignisse von einer Upstream-Komponente zu sagen, füttern den Offset-param zu dem Clonetainer)

Die Lösung, die ich für das Stoppen des Updates fand, beinhaltete das Bestimmen, ob der Clonetainer aufgrund einer Bewegung oder eines anderen Grundes ausgelöst wurde (und entsprechend this.isMoveEvent) und dann eine Komponente zwischen dem Clonetainer und dem Kinder, die aus nichts anderem als einem shouldComponentUpdate bestehen eine eingefügte Stütze (shouldUpdate).

Das funktioniert. Ich habe es auf eine Weise getestet, die zeigt, dass es aktualisiert wird, wenn es sollte, und nicht aktualisiert, wenn es nicht sollte, aber es fühlt sich ein wenig nach Overkill an, um eine separate Shim-Komponente darin zu haben, um Updates vom Downhill zu blockieren. Gibt es eine Möglichkeit, anzugeben, dass eine untergeordnete Komponente in render nicht von seinem vorherigen Status aktualisiert werden soll, ohne dass die untergeordnete Komponente ihre eigene -Logik einbeziehen muss?

+3

Ich denke, Ihre Vorgehensweise ist korrekt und die beste verfügbar. Ein anderer Ansatz wäre, den DOM-Knoten für den 'Clonetainer' während des Ziehens direkt zu manipulieren. – VonD

Antwort

1

Sie sollten in der Lage sein, componentWillReceiveProps zu in der Clonetainer Komponente zu ändern und den mittleren Mann ausschneiden. shouldComponentUpdate nimmt zwei Parameter, (object nextProps, object nextState), die Sie verwenden können, um gegen this.state und this.props zu vergleichen. Die Rückgabe von "true" führt zu einem erneuten Rendern.

const Clonetainer = React.createClass({ 
    shouldComponentUpdate: function (nextProps, nextState) { 
     // OR in any further properties that may indicate a move, versus a child update 
     this.props.offset !== nextProps.offset; 
    }, 
    render: function() { 
     const style = { transform: `translate(${this.props.offset.left}px,${this.props.offset.top}px)` }; 
     return <div className="clonetainer-div" style={style}> 
      { this.props.children } 
     </div>; 
    } 
}); 
+0

Das würde mich nicht die Positionierung auf dem Clonetainer ändern lassen, oder? Das Problem, das ich hatte, kam, wenn die Position des Clonetainers geändert werden muss (also muss es neu gerendert werden), aber keine der Daten des Inhalts hat (so sollten sie nicht). Mit sollteComponentUpdate würde ich erwarten, dass Sie entweder "all" erhalten (sollteComponentUpdate gibt true und die gesamte Struktur neu gerendert wird) oder "nichts" (sollteComponentUpdate gibt false zurück und überhaupt nichts über Änderungen). – SuperFLEB

Verwandte Themen