Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 101 additions & 21 deletions src/renderers/shared/stack/reconciler/ReactCompositeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,15 @@ var CompositeTypes = {
StatelessFunctional: 2,
};

function StatelessComponent(Component) {
function StatelessComponent(Component, props, context, updater) {
this.props = props;
this.context = context;
this.updater = updater;

this.refs = emptyObject;
this.state = null;
}

StatelessComponent.prototype.render = function() {
var Component = ReactInstanceMap.get(this)._currentElement.type;
var element = Component(this.props, this.context, this.updater);
Expand Down Expand Up @@ -219,8 +226,8 @@ var ReactCompositeComponentMixin = {
);
var renderedElement;

// Support functional components
if (!doConstruct && (inst == null || inst.render == null)) {
// is a stateless functional component (SFC)
renderedElement = inst;
warnIfInvalidElement(Component, renderedElement);
invariant(
Expand All @@ -231,14 +238,33 @@ var ReactCompositeComponentMixin = {
'returned undefined, an array or some other invalid object.',
Component.displayName || Component.name || 'Component'
);
inst = new StatelessComponent(Component);
inst = new StatelessComponent(
Component,
publicProps,
publicContext,
updateQueue
);
this._compositeType = CompositeTypes.StatelessFunctional;

this._instance = inst;

// Store a reference from the instance back to the internal representation
ReactInstanceMap.set(inst, this);

// SFC: skip redundant assertions
return this._getMarkupForSFC(
renderedElement,
hostParent,
hostContainerInfo,
transaction,
context
);
}

if (isPureComponent(Component)) {
this._compositeType = CompositeTypes.PureClass;
} else {
if (isPureComponent(Component)) {
this._compositeType = CompositeTypes.PureClass;
} else {
this._compositeType = CompositeTypes.ImpureClass;
}
this._compositeType = CompositeTypes.ImpureClass;
}

if (__DEV__) {
Expand Down Expand Up @@ -342,21 +368,16 @@ var ReactCompositeComponentMixin = {
this.getName() || 'ReactCompositeComponent'
);

this._pendingStateQueue = null;
this._pendingReplaceState = false;
this._pendingForceUpdate = false;

var markup;
if (inst.unstable_handleError) {
markup = this.performInitialMountWithErrorHandling(
renderedElement,
hostParent,
hostContainerInfo,
transaction,
context
);
} else {
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
markup = this.performInitialMount(hostParent, hostContainerInfo, transaction, context);
}

if (inst.componentDidMount) {
Expand All @@ -377,6 +398,31 @@ var ReactCompositeComponentMixin = {
return markup;
},

_getMarkupForSFC: function(
renderedElement,
hostParent,
hostContainerInfo,
transaction,
context
) {
var markup = this.performInitialMountForSFC(
renderedElement,
hostParent,
hostContainerInfo,
transaction,
context
);

if (__DEV__) {
if (this._debugID) {
var callback = (component) => ReactInstrumentation.debugTool.onComponentHasMounted(this._debugID);
transaction.getReactMountReady().enqueue(callback, this);
}
}

return markup;
},

_constructComponent: function(
doConstruct,
publicProps,
Expand Down Expand Up @@ -456,7 +502,6 @@ var ReactCompositeComponentMixin = {
},

performInitialMountWithErrorHandling: function(
renderedElement,
hostParent,
hostContainerInfo,
transaction,
Expand All @@ -465,7 +510,7 @@ var ReactCompositeComponentMixin = {
var markup;
var checkpoint = transaction.checkpoint();
try {
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
markup = this.performInitialMount(hostParent, hostContainerInfo, transaction, context);
} catch (e) {
if (__DEV__) {
if (this._debugID !== 0) {
Expand All @@ -485,13 +530,14 @@ var ReactCompositeComponentMixin = {

// Try again - we've informed the component about the error, so they can render an error message this time.
// If this throws again, the error will bubble up (and can be caught by a higher error boundary).
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
markup = this.performInitialMount(hostParent, hostContainerInfo, transaction, context);
}
return markup;
},

performInitialMount: function(renderedElement, hostParent, hostContainerInfo, transaction, context) {
performInitialMount: function(hostParent, hostContainerInfo, transaction, context) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this method be private too?

var inst = this._instance;
var renderedElement;
if (inst.componentWillMount) {
if (__DEV__) {
if (this._debugID !== 0) {
Expand All @@ -517,11 +563,45 @@ var ReactCompositeComponentMixin = {
}
}

// If not a stateless component, we now render
if (renderedElement === undefined) {
renderedElement = this._renderValidatedComponent();
renderedElement = this._renderValidatedComponent();

var nodeType = ReactNodeTypes.getType(renderedElement);
this._renderedNodeType = nodeType;
var child = this._instantiateReactComponent(
renderedElement,
nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */
);
this._renderedComponent = child;
if (__DEV__) {
if (child._debugID !== 0 && this._debugID !== 0) {
ReactInstrumentation.debugTool.onSetParent(
child._debugID,
this._debugID
);
}
}

var markup = ReactReconciler.mountComponent(
child,
transaction,
hostParent,
hostContainerInfo,
this._processChildContext(context)
);

if (__DEV__) {
if (this._debugID !== 0) {
ReactInstrumentation.debugTool.onSetChildren(
this._debugID,
child._debugID !== 0 ? [child._debugID] : []
);
}
}

return markup;
},

performInitialMountForSFC: function(renderedElement, hostParent, hostContainerInfo, transaction, context) {
var nodeType = ReactNodeTypes.getType(renderedElement);
this._renderedNodeType = nodeType;
var child = this._instantiateReactComponent(
Expand Down