@samitouri / QOS-React / commits / dbe3584340

Remove the Mixin layer of indirection on ReactMultiChild (#7598)

As mentioned in https://github.com/facebook/react/pull/7581#issuecomment-242952042 we can remove the Mixin layer of indirection as it only exports a Mixin and I find it confusing.

Christopher Chedeau committed Aug 28, 2016 at 16:46 UTC dbe3584340a7a9c74a89ae66007d533ef7130973
5 files changed +309 -323
src/renderers/art/ReactART.js
+2 -2
@@ -93,7 +93,7 @@ function injectAfter(parentNode, referenceNode, node) {
93
94 // ContainerMixin for components that can hold ART nodes
95
96 -const ContainerMixin = assign({}, ReactMultiChild.Mixin, {
96 +const ContainerMixin = assign({}, ReactMultiChild, {
97
98 /**
99 * Moves a child component to the supplied index.
@@ -144,7 +144,7 @@ const ContainerMixin = assign({}, ReactMultiChild.Mixin, {
144 * @param {?object} nextChildren.
145 * @param {ReactReconcileTransaction} transaction
146 * @internal
147 - * @override {ReactMultiChild.Mixin.updateChildren}
147 + * @override {ReactMultiChild.updateChildren}
148 */
149 updateChildren: function(nextChildren, transaction, context) {
150 this._updateChildren(nextChildren, transaction, context);
src/renderers/dom/shared/ReactDOMComponent.js
+1 -1
@@ -1210,7 +1210,7 @@ ReactDOMComponent.Mixin = {
1210 Object.assign(
1211 ReactDOMComponent.prototype,
1212 ReactDOMComponent.Mixin,
1213 - ReactMultiChild.Mixin
1213 + ReactMultiChild
1214 );
1215
1216 module.exports = ReactDOMComponent;
src/renderers/native/ReactNativeBaseComponent.js
+1 -1
@@ -224,7 +224,7 @@ ReactNativeBaseComponent.Mixin = {
224 */
225 Object.assign(
226 ReactNativeBaseComponent.prototype,
227 - ReactMultiChild.Mixin,
227 + ReactMultiChild,
228 ReactNativeBaseComponent.Mixin,
229 NativeMethodsMixin
230 );
src/renderers/shared/stack/reconciler/ReactMultiChild.js
+304 -318
@@ -165,357 +165,343 @@ if (__DEV__) {
165 }
166
167 /**
168 - * ReactMultiChild are capable of reconciling multiple children.
169 - *
170 - * @class ReactMultiChild
171 - * @internal
168 + * Provides common functionality for components that must reconcile multiple
169 + * children. This is used by `ReactDOMComponent` to mount, update, and
170 + * unmount child components.
171 */
172 var ReactMultiChild = {
174 -
175 - /**
176 - * Provides common functionality for components that must reconcile multiple
177 - * children. This is used by `ReactDOMComponent` to mount, update, and
178 - * unmount child components.
179 - *
180 - * @lends {ReactMultiChild.prototype}
181 - */
182 - Mixin: {
183 -
184 - _reconcilerInstantiateChildren: function(nestedChildren, transaction, context) {
185 - if (__DEV__) {
186 - var selfDebugID = getDebugID(this);
187 - if (this._currentElement) {
188 - try {
189 - ReactCurrentOwner.current = this._currentElement._owner;
190 - return ReactChildReconciler.instantiateChildren(
191 - nestedChildren, transaction, context, selfDebugID
192 - );
193 - } finally {
194 - ReactCurrentOwner.current = null;
195 - }
173 + _reconcilerInstantiateChildren: function(nestedChildren, transaction, context) {
174 + if (__DEV__) {
175 + var selfDebugID = getDebugID(this);
176 + if (this._currentElement) {
177 + try {
178 + ReactCurrentOwner.current = this._currentElement._owner;
179 + return ReactChildReconciler.instantiateChildren(
180 + nestedChildren, transaction, context, selfDebugID
181 + );
182 + } finally {
183 + ReactCurrentOwner.current = null;
184 }
185 }
198 - return ReactChildReconciler.instantiateChildren(
199 - nestedChildren, transaction, context
200 - );
201 - },
186 + }
187 + return ReactChildReconciler.instantiateChildren(
188 + nestedChildren, transaction, context
189 + );
190 + },
191
203 - _reconcilerUpdateChildren: function(
192 + _reconcilerUpdateChildren: function(
193 + prevChildren,
194 + nextNestedChildrenElements,
195 + mountImages,
196 + removedNodes,
197 + transaction,
198 + context
199 + ) {
200 + var nextChildren;
201 + var selfDebugID = 0;
202 + if (__DEV__) {
203 + selfDebugID = getDebugID(this);
204 + if (this._currentElement) {
205 + try {
206 + ReactCurrentOwner.current = this._currentElement._owner;
207 + nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID);
208 + } finally {
209 + ReactCurrentOwner.current = null;
210 + }
211 + ReactChildReconciler.updateChildren(
212 + prevChildren,
213 + nextChildren,
214 + mountImages,
215 + removedNodes,
216 + transaction,
217 + this,
218 + this._hostContainerInfo,
219 + context,
220 + selfDebugID
221 + );
222 + return nextChildren;
223 + }
224 + }
225 + nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID);
226 + ReactChildReconciler.updateChildren(
227 prevChildren,
205 - nextNestedChildrenElements,
228 + nextChildren,
229 mountImages,
230 removedNodes,
231 transaction,
209 - context
210 - ) {
211 - var nextChildren;
212 - var selfDebugID = 0;
213 - if (__DEV__) {
214 - selfDebugID = getDebugID(this);
215 - if (this._currentElement) {
216 - try {
217 - ReactCurrentOwner.current = this._currentElement._owner;
218 - nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID);
219 - } finally {
220 - ReactCurrentOwner.current = null;
221 - }
222 - ReactChildReconciler.updateChildren(
223 - prevChildren,
224 - nextChildren,
225 - mountImages,
226 - removedNodes,
227 - transaction,
228 - this,
229 - this._hostContainerInfo,
230 - context,
231 - selfDebugID
232 - );
233 - return nextChildren;
234 - }
235 - }
236 - nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID);
237 - ReactChildReconciler.updateChildren(
238 - prevChildren,
239 - nextChildren,
240 - mountImages,
241 - removedNodes,
242 - transaction,
243 - this,
244 - this._hostContainerInfo,
245 - context,
246 - selfDebugID
247 - );
248 - return nextChildren;
249 - },
250 -
251 - /**
252 - * Generates a "mount image" for each of the supplied children. In the case
253 - * of `ReactDOMComponent`, a mount image is a string of markup.
254 - *
255 - * @param {?object} nestedChildren Nested child maps.
256 - * @return {array} An array of mounted representations.
257 - * @internal
258 - */
259 - mountChildren: function(nestedChildren, transaction, context) {
260 - var children = this._reconcilerInstantiateChildren(
261 - nestedChildren, transaction, context
262 - );
263 - this._renderedChildren = children;
232 + this,
233 + this._hostContainerInfo,
234 + context,
235 + selfDebugID
236 + );
237 + return nextChildren;
238 + },
239
265 - var mountImages = [];
266 - var index = 0;
267 - for (var name in children) {
268 - if (children.hasOwnProperty(name)) {
269 - var child = children[name];
270 - var selfDebugID = 0;
271 - if (__DEV__) {
272 - selfDebugID = getDebugID(this);
273 - }
274 - var mountImage = ReactReconciler.mountComponent(
275 - child,
276 - transaction,
277 - this,
278 - this._hostContainerInfo,
279 - context,
280 - selfDebugID
281 - );
282 - child._mountIndex = index++;
283 - mountImages.push(mountImage);
240 + /**
241 + * Generates a "mount image" for each of the supplied children. In the case
242 + * of `ReactDOMComponent`, a mount image is a string of markup.
243 + *
244 + * @param {?object} nestedChildren Nested child maps.
245 + * @return {array} An array of mounted representations.
246 + * @internal
247 + */
248 + mountChildren: function(nestedChildren, transaction, context) {
249 + var children = this._reconcilerInstantiateChildren(
250 + nestedChildren, transaction, context
251 + );
252 + this._renderedChildren = children;
253 +
254 + var mountImages = [];
255 + var index = 0;
256 + for (var name in children) {
257 + if (children.hasOwnProperty(name)) {
258 + var child = children[name];
259 + var selfDebugID = 0;
260 + if (__DEV__) {
261 + selfDebugID = getDebugID(this);
262 }
263 + var mountImage = ReactReconciler.mountComponent(
264 + child,
265 + transaction,
266 + this,
267 + this._hostContainerInfo,
268 + context,
269 + selfDebugID
270 + );
271 + child._mountIndex = index++;
272 + mountImages.push(mountImage);
273 }
274 + }
275
287 - if (__DEV__) {
288 - setChildrenForInstrumentation.call(this, children);
289 - }
276 + if (__DEV__) {
277 + setChildrenForInstrumentation.call(this, children);
278 + }
279
291 - return mountImages;
292 - },
280 + return mountImages;
281 + },
282
294 - /**
295 - * Replaces any rendered children with a text content string.
296 - *
297 - * @param {string} nextContent String of content.
298 - * @internal
299 - */
300 - updateTextContent: function(nextContent) {
301 - var prevChildren = this._renderedChildren;
302 - // Remove any rendered children.
303 - ReactChildReconciler.unmountChildren(prevChildren, false);
304 - for (var name in prevChildren) {
305 - if (prevChildren.hasOwnProperty(name)) {
306 - invariant(false, 'updateTextContent called on non-empty component.');
307 - }
283 + /**
284 + * Replaces any rendered children with a text content string.
285 + *
286 + * @param {string} nextContent String of content.
287 + * @internal
288 + */
289 + updateTextContent: function(nextContent) {
290 + var prevChildren = this._renderedChildren;
291 + // Remove any rendered children.
292 + ReactChildReconciler.unmountChildren(prevChildren, false);
293 + for (var name in prevChildren) {
294 + if (prevChildren.hasOwnProperty(name)) {
295 + invariant(false, 'updateTextContent called on non-empty component.');
296 }
309 - // Set new text content.
310 - var updates = [makeTextContent(nextContent)];
311 - processQueue(this, updates);
312 - },
297 + }
298 + // Set new text content.
299 + var updates = [makeTextContent(nextContent)];
300 + processQueue(this, updates);
301 + },
302
314 - /**
315 - * Replaces any rendered children with a markup string.
316 - *
317 - * @param {string} nextMarkup String of markup.
318 - * @internal
319 - */
320 - updateMarkup: function(nextMarkup) {
321 - var prevChildren = this._renderedChildren;
322 - // Remove any rendered children.
323 - ReactChildReconciler.unmountChildren(prevChildren, false);
324 - for (var name in prevChildren) {
325 - if (prevChildren.hasOwnProperty(name)) {
326 - invariant(false, 'updateTextContent called on non-empty component.');
327 - }
303 + /**
304 + * Replaces any rendered children with a markup string.
305 + *
306 + * @param {string} nextMarkup String of markup.
307 + * @internal
308 + */
309 + updateMarkup: function(nextMarkup) {
310 + var prevChildren = this._renderedChildren;
311 + // Remove any rendered children.
312 + ReactChildReconciler.unmountChildren(prevChildren, false);
313 + for (var name in prevChildren) {
314 + if (prevChildren.hasOwnProperty(name)) {
315 + invariant(false, 'updateTextContent called on non-empty component.');
316 }
329 - var updates = [makeSetMarkup(nextMarkup)];
330 - processQueue(this, updates);
331 - },
317 + }
318 + var updates = [makeSetMarkup(nextMarkup)];
319 + processQueue(this, updates);
320 + },
321
333 - /**
334 - * Updates the rendered children with new children.
335 - *
336 - * @param {?object} nextNestedChildrenElements Nested child element maps.
337 - * @param {ReactReconcileTransaction} transaction
338 - * @internal
339 - */
340 - updateChildren: function(nextNestedChildrenElements, transaction, context) {
341 - // Hook used by React ART
342 - this._updateChildren(nextNestedChildrenElements, transaction, context);
343 - },
322 + /**
323 + * Updates the rendered children with new children.
324 + *
325 + * @param {?object} nextNestedChildrenElements Nested child element maps.
326 + * @param {ReactReconcileTransaction} transaction
327 + * @internal
328 + */
329 + updateChildren: function(nextNestedChildrenElements, transaction, context) {
330 + // Hook used by React ART
331 + this._updateChildren(nextNestedChildrenElements, transaction, context);
332 + },
333
345 - /**
346 - * @param {?object} nextNestedChildrenElements Nested child element maps.
347 - * @param {ReactReconcileTransaction} transaction
348 - * @final
349 - * @protected
350 - */
351 - _updateChildren: function(nextNestedChildrenElements, transaction, context) {
352 - var prevChildren = this._renderedChildren;
353 - var removedNodes = {};
354 - var mountImages = [];
355 - var nextChildren = this._reconcilerUpdateChildren(
356 - prevChildren,
357 - nextNestedChildrenElements,
358 - mountImages,
359 - removedNodes,
360 - transaction,
361 - context
362 - );
363 - if (!nextChildren && !prevChildren) {
364 - return;
334 + /**
335 + * @param {?object} nextNestedChildrenElements Nested child element maps.
336 + * @param {ReactReconcileTransaction} transaction
337 + * @final
338 + * @protected
339 + */
340 + _updateChildren: function(nextNestedChildrenElements, transaction, context) {
341 + var prevChildren = this._renderedChildren;
342 + var removedNodes = {};
343 + var mountImages = [];
344 + var nextChildren = this._reconcilerUpdateChildren(
345 + prevChildren,
346 + nextNestedChildrenElements,
347 + mountImages,
348 + removedNodes,
349 + transaction,
350 + context
351 + );
352 + if (!nextChildren && !prevChildren) {
353 + return;
354 + }
355 + var updates = null;
356 + var name;
357 + // `nextIndex` will increment for each child in `nextChildren`, but
358 + // `lastIndex` will be the last index visited in `prevChildren`.
359 + var nextIndex = 0;
360 + var lastIndex = 0;
361 + // `nextMountIndex` will increment for each newly mounted child.
362 + var nextMountIndex = 0;
363 + var lastPlacedNode = null;
364 + for (name in nextChildren) {
365 + if (!nextChildren.hasOwnProperty(name)) {
366 + continue;
367 }
366 - var updates = null;
367 - var name;
368 - // `nextIndex` will increment for each child in `nextChildren`, but
369 - // `lastIndex` will be the last index visited in `prevChildren`.
370 - var nextIndex = 0;
371 - var lastIndex = 0;
372 - // `nextMountIndex` will increment for each newly mounted child.
373 - var nextMountIndex = 0;
374 - var lastPlacedNode = null;
375 - for (name in nextChildren) {
376 - if (!nextChildren.hasOwnProperty(name)) {
377 - continue;
378 - }
379 - var prevChild = prevChildren && prevChildren[name];
380 - var nextChild = nextChildren[name];
381 - if (prevChild === nextChild) {
382 - updates = enqueue(
383 - updates,
384 - this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex)
385 - );
368 + var prevChild = prevChildren && prevChildren[name];
369 + var nextChild = nextChildren[name];
370 + if (prevChild === nextChild) {
371 + updates = enqueue(
372 + updates,
373 + this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex)
374 + );
375 + lastIndex = Math.max(prevChild._mountIndex, lastIndex);
376 + prevChild._mountIndex = nextIndex;
377 + } else {
378 + if (prevChild) {
379 + // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
380 lastIndex = Math.max(prevChild._mountIndex, lastIndex);
387 - prevChild._mountIndex = nextIndex;
388 - } else {
389 - if (prevChild) {
390 - // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
391 - lastIndex = Math.max(prevChild._mountIndex, lastIndex);
392 - // The `removedNodes` loop below will actually remove the child.
393 - }
394 - // The child must be instantiated before it's mounted.
395 - updates = enqueue(
396 - updates,
397 - this._mountChildAtIndex(
398 - nextChild,
399 - mountImages[nextMountIndex],
400 - lastPlacedNode,
401 - nextIndex,
402 - transaction,
403 - context
404 - )
405 - );
406 - nextMountIndex++;
407 - }
408 - nextIndex++;
409 - lastPlacedNode = ReactReconciler.getHostNode(nextChild);
410 - }
411 - // Remove children that are no longer present.
412 - for (name in removedNodes) {
413 - if (removedNodes.hasOwnProperty(name)) {
414 - updates = enqueue(
415 - updates,
416 - this._unmountChild(prevChildren[name], removedNodes[name])
417 - );
381 + // The `removedNodes` loop below will actually remove the child.
382 }
383 + // The child must be instantiated before it's mounted.
384 + updates = enqueue(
385 + updates,
386 + this._mountChildAtIndex(
387 + nextChild,
388 + mountImages[nextMountIndex],
389 + lastPlacedNode,
390 + nextIndex,
391 + transaction,
392 + context
393 + )
394 + );
395 + nextMountIndex++;
396 }
420 - if (updates) {
421 - processQueue(this, updates);
422 - }
423 - this._renderedChildren = nextChildren;
424 -
425 - if (__DEV__) {
426 - setChildrenForInstrumentation.call(this, nextChildren);
397 + nextIndex++;
398 + lastPlacedNode = ReactReconciler.getHostNode(nextChild);
399 + }
400 + // Remove children that are no longer present.
401 + for (name in removedNodes) {
402 + if (removedNodes.hasOwnProperty(name)) {
403 + updates = enqueue(
404 + updates,
405 + this._unmountChild(prevChildren[name], removedNodes[name])
406 + );
407 }
428 - },
429 -
430 - /**
431 - * Unmounts all rendered children. This should be used to clean up children
432 - * when this component is unmounted. It does not actually perform any
433 - * backend operations.
434 - *
435 - * @internal
436 - */
437 - unmountChildren: function(safely) {
438 - var renderedChildren = this._renderedChildren;
439 - ReactChildReconciler.unmountChildren(renderedChildren, safely);
440 - this._renderedChildren = null;
441 - },
408 + }
409 + if (updates) {
410 + processQueue(this, updates);
411 + }
412 + this._renderedChildren = nextChildren;
413
443 - /**
444 - * Moves a child component to the supplied index.
445 - *
446 - * @param {ReactComponent} child Component to move.
447 - * @param {number} toIndex Destination index of the element.
448 - * @param {number} lastIndex Last index visited of the siblings of `child`.
449 - * @protected
450 - */
451 - moveChild: function(child, afterNode, toIndex, lastIndex) {
452 - // If the index of `child` is less than `lastIndex`, then it needs to
453 - // be moved. Otherwise, we do not need to move it because a child will be
454 - // inserted or moved before `child`.
455 - if (child._mountIndex < lastIndex) {
456 - return makeMove(child, afterNode, toIndex);
457 - }
458 - },
414 + if (__DEV__) {
415 + setChildrenForInstrumentation.call(this, nextChildren);
416 + }
417 + },
418
460 - /**
461 - * Creates a child component.
462 - *
463 - * @param {ReactComponent} child Component to create.
464 - * @param {string} mountImage Markup to insert.
465 - * @protected
466 - */
467 - createChild: function(child, afterNode, mountImage) {
468 - return makeInsertMarkup(mountImage, afterNode, child._mountIndex);
469 - },
419 + /**
420 + * Unmounts all rendered children. This should be used to clean up children
421 + * when this component is unmounted. It does not actually perform any
422 + * backend operations.
423 + *
424 + * @internal
425 + */
426 + unmountChildren: function(safely) {
427 + var renderedChildren = this._renderedChildren;
428 + ReactChildReconciler.unmountChildren(renderedChildren, safely);
429 + this._renderedChildren = null;
430 + },
431
471 - /**
472 - * Removes a child component.
473 - *
474 - * @param {ReactComponent} child Child to remove.
475 - * @protected
476 - */
477 - removeChild: function(child, node) {
478 - return makeRemove(child, node);
479 - },
432 + /**
433 + * Moves a child component to the supplied index.
434 + *
435 + * @param {ReactComponent} child Component to move.
436 + * @param {number} toIndex Destination index of the element.
437 + * @param {number} lastIndex Last index visited of the siblings of `child`.
438 + * @protected
439 + */
440 + moveChild: function(child, afterNode, toIndex, lastIndex) {
441 + // If the index of `child` is less than `lastIndex`, then it needs to
442 + // be moved. Otherwise, we do not need to move it because a child will be
443 + // inserted or moved before `child`.
444 + if (child._mountIndex < lastIndex) {
445 + return makeMove(child, afterNode, toIndex);
446 + }
447 + },
448
481 - /**
482 - * Mounts a child with the supplied name.
483 - *
484 - * NOTE: This is part of `updateChildren` and is here for readability.
485 - *
486 - * @param {ReactComponent} child Component to mount.
487 - * @param {string} name Name of the child.
488 - * @param {number} index Index at which to insert the child.
489 - * @param {ReactReconcileTransaction} transaction
490 - * @private
491 - */
492 - _mountChildAtIndex: function(
493 - child,
494 - mountImage,
495 - afterNode,
496 - index,
497 - transaction,
498 - context) {
499 - child._mountIndex = index;
500 - return this.createChild(child, afterNode, mountImage);
501 - },
449 + /**
450 + * Creates a child component.
451 + *
452 + * @param {ReactComponent} child Component to create.
453 + * @param {string} mountImage Markup to insert.
454 + * @protected
455 + */
456 + createChild: function(child, afterNode, mountImage) {
457 + return makeInsertMarkup(mountImage, afterNode, child._mountIndex);
458 + },
459
503 - /**
504 - * Unmounts a rendered child.
505 - *
506 - * NOTE: This is part of `updateChildren` and is here for readability.
507 - *
508 - * @param {ReactComponent} child Component to unmount.
509 - * @private
510 - */
511 - _unmountChild: function(child, node) {
512 - var update = this.removeChild(child, node);
513 - child._mountIndex = null;
514 - return update;
515 - },
460 + /**
461 + * Removes a child component.
462 + *
463 + * @param {ReactComponent} child Child to remove.
464 + * @protected
465 + */
466 + removeChild: function(child, node) {
467 + return makeRemove(child, node);
468 + },
469
470 + /**
471 + * Mounts a child with the supplied name.
472 + *
473 + * NOTE: This is part of `updateChildren` and is here for readability.
474 + *
475 + * @param {ReactComponent} child Component to mount.
476 + * @param {string} name Name of the child.
477 + * @param {number} index Index at which to insert the child.
478 + * @param {ReactReconcileTransaction} transaction
479 + * @private
480 + */
481 + _mountChildAtIndex: function(
482 + child,
483 + mountImage,
484 + afterNode,
485 + index,
486 + transaction,
487 + context) {
488 + child._mountIndex = index;
489 + return this.createChild(child, afterNode, mountImage);
490 },
491
492 + /**
493 + * Unmounts a rendered child.
494 + *
495 + * NOTE: This is part of `updateChildren` and is here for readability.
496 + *
497 + * @param {ReactComponent} child Component to unmount.
498 + * @private
499 + */
500 + _unmountChild: function(child, node) {
501 + var update = this.removeChild(child, node);
502 + child._mountIndex = null;
503 + return update;
504 + },
505 };
506
507 module.exports = ReactMultiChild;
src/renderers/testing/ReactTestRenderer.js
+1 -1
@@ -88,7 +88,7 @@ ReactTestComponent.prototype.toJSON = function() {
88 });
89 return object;
90 };
91 -Object.assign(ReactTestComponent.prototype, ReactMultiChild.Mixin);
91 +Object.assign(ReactTestComponent.prototype, ReactMultiChild);
92
93 // =============================================================================
94