Skip to content

Commit

Permalink
Clone on mount
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sebmarkbage authored and zpao committed Mar 10, 2014
1 parent 2ca810f commit 3ea3274
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 102 deletions.
10 changes: 10 additions & 0 deletions src/browser/ReactTextComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand Down
5 changes: 3 additions & 2 deletions src/browser/server/ReactServerRendering.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var ReactMarkupChecksum = require('ReactMarkupChecksum');
var ReactServerRenderingTransaction =
require('ReactServerRenderingTransaction');


var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant');

/**
Expand All @@ -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 {
Expand Down
12 changes: 9 additions & 3 deletions src/browser/ui/ReactMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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
Expand All @@ -309,7 +315,7 @@ var ReactMount = {
getReactRootElementInContainer(container);
}

return nextComponent;
return componentInstance;
}
),

Expand Down
Loading

0 comments on commit 3ea3274

Please sign in to comment.