Clone on mount

This is the first step towards descriptors. This will start cloning the
component when it's mounted instead of mounting the first instance.

This avoids an issue where a reference to the first instance can hang around
in props. Since a mounted component gets mutated, the descriptor changes.

We don't need to clone the props object itself. Mutating the shallow props
object of a child that's passed into you is already flawed. Those cases need to
use cloneWithProps. A props object is considered shallow frozen after it leaves
the render it was created in.
This commit is contained in:
Sebastian Markbage
2014-03-10 15:26:31 -07:00
committed by Paul O’Shannessy
parent 2ca810fbf3
commit 3ea3274ca4
11 changed files with 312 additions and 102 deletions
+10
View File
@@ -45,6 +45,16 @@ var ReactTextComponent = function(initialText) {
this.construct({text: initialText});
};
/**
* Used to clone the text descriptor object before it's mounted.
*
* @param {object} props
* @return {object} A new ReactTextComponent instance
*/
ReactTextComponent.ConvenienceConstructor = function(props) {
return new ReactTextComponent(props.text);
};
mixInto(ReactTextComponent, ReactComponent.Mixin);
mixInto(ReactTextComponent, ReactBrowserComponentMixin);
mixInto(ReactTextComponent, {
+3 -2
View File
@@ -24,7 +24,7 @@ var ReactMarkupChecksum = require('ReactMarkupChecksum');
var ReactServerRenderingTransaction =
require('ReactServerRenderingTransaction');
var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant');
/**
@@ -49,7 +49,8 @@ function renderComponentToString(component) {
transaction = ReactServerRenderingTransaction.getPooled(false);
return transaction.perform(function() {
var markup = component.mountComponent(id, transaction, 0);
var componentInstance = instantiateReactComponent(component);
var markup = componentInstance.mountComponent(id, transaction, 0);
return ReactMarkupChecksum.addChecksumToMarkup(markup);
}, null);
} finally {
+9 -3
View File
@@ -25,6 +25,7 @@ var ReactPerf = require('ReactPerf');
var containsNode = require('containsNode');
var getReactRootElementInContainer = require('getReactRootElementInContainer');
var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant');
var shouldUpdateReactComponent = require('shouldUpdateReactComponent');
@@ -296,8 +297,13 @@ var ReactMount = {
nextComponent,
container,
shouldReuseMarkup) {
var reactRootID = ReactMount._registerComponent(nextComponent, container);
nextComponent.mountComponentIntoNode(
var componentInstance = instantiateReactComponent(nextComponent);
var reactRootID = ReactMount._registerComponent(
componentInstance,
container
);
componentInstance.mountComponentIntoNode(
reactRootID,
container,
shouldReuseMarkup
@@ -309,7 +315,7 @@ var ReactMount = {
getReactRootElementInContainer(container);
}
return nextComponent;
return componentInstance;
}
),