Sto lavorando a un'implementazione Drag-and-drop (da zero, non utilizzando una libreria DND) e volevo limitare il numero di aggiornamenti non necessari durante il trascinamento.React: il modo migliore per aggiornare se stessi, ma impedire l'aggiornamento dei bambini?
Il trascinamento del "clone" (che di solito è una copia dell'elemento originale, ma può essere un segnaposto arbitrario) si ottiene aggiornando uno stato su un componente contenitore (il "Clonetainer") e utilizzando quello per applicare una trasformazione . Tuttavia, non ha senso aggiornare l'intero sottoalbero durante una mossa, poiché l'unico cambiamento sono le coordinate del contenitore.
Ecco la mia soluzione a questo:
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>;
}
});
(non voglio entrare nei dettagli sul resto del sistema DND, se non per dire che gli eventi del mouse da un componente a monte alimentano il parametro offset al Clonetainer.)
la soluzione mi è venuta per fermare l'aggiornamento ha coinvolto determinare se la Clonetainer è stato innescato per aggiornare a causa di un movimento o di qualche altro motivo (e l'impostazione this.isMoveEvent
di conseguenza), quindi spessori un componente tra il Clonetainer ed il bambini che consistono in nient'altro che un UpdateComponentUpdate basato su un puntello passato (shouldUpdate
).
Questo funziona. L'ho provato in un modo che mostra che si sta aggiornando quando dovrebbe e non si aggiorna quando non dovrebbe, ma sembra un po 'eccessivo avere un componente di shim separato semplicemente per bloccare gli aggiornamenti dal downhill. C'è un modo per indicare che un componente figlio non deve essere aggiornato dal suo stato precedente in render
, senza richiedere che il componente figlio includa la propria logica shouldComponentUpdate
?
Penso che il tuo approccio sia corretto e il migliore disponibile. Un altro approccio sarebbe quello di manipolare direttamente il nodo DOM per il 'Clonetainer' durante il trascinamento – VonD