Skip to content
Merged
Show file tree
Hide file tree
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
30 changes: 20 additions & 10 deletions src/renderers/shared/reconciler/ReactCompositeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function StatelessComponent(Component) {
}
StatelessComponent.prototype.render = function() {
var Component = ReactInstanceMap.get(this)._currentElement.type;
return new Component(this.props, this.context, this.updater);
return Component(this.props, this.context, this.updater);
};

/**
Expand Down Expand Up @@ -136,18 +136,26 @@ var ReactCompositeComponentMixin = {
var inst;
var renderedElement;

if (__DEV__) {
ReactCurrentOwner.current = this;
try {
// This is a way to detect if Component is a stateless arrow function
// component, which is not newable. It might not be 100% reliable but is
// something we can do until we start detecting that Component extends
// React.Component. We already assume that typeof Component === 'function'.
var canInstantiate = 'prototype' in Component;

if (canInstantiate) {
if (__DEV__) {
ReactCurrentOwner.current = this;
try {
inst = new Component(publicProps, publicContext, ReactUpdateQueue);
} finally {
ReactCurrentOwner.current = null;
}
} else {
inst = new Component(publicProps, publicContext, ReactUpdateQueue);
} finally {
ReactCurrentOwner.current = null;
}
} else {
inst = new Component(publicProps, publicContext, ReactUpdateQueue);
}

if (inst === null || inst === false || ReactElement.isValidElement(inst)) {
if (!canInstantiate || inst === null || inst === false || ReactElement.isValidElement(inst)) {
renderedElement = inst;
inst = new StatelessComponent(Component);
}
Expand All @@ -168,7 +176,9 @@ var ReactCompositeComponentMixin = {
// We support ES6 inheriting from React.Component, the module pattern,
// and stateless components, but not ES6 classes that don't extend
warning(
Component.isReactClass || !(inst instanceof Component),
Component.isReactClass ||
!canInstantiate ||
!(inst instanceof Component),
'%s(...): React component classes must extend React.Component.',
Component.displayName || Component.name || 'Component'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,19 @@ describe('ReactStatelessComponent', function() {
ReactDOM.render(<Parent />, el);
expect(el.textContent).toBe('en');
});

it('should work with arrow functions', function() {
// TODO: actually use arrow functions, probably need node v4 and maybe
// a separate file that we blacklist from the arrow function transform.
// We can't actually test this without native arrow functions since the
// issues (non-newable) don't apply to any other functions.
var Child = function() {
return <div />;
};
// Will create a new bound function without a prototype, much like a native
// arrow function.
Child = Child.bind(this);

expect(() => ReactTestUtils.renderIntoDocument(<Child />)).not.toThrow();
});
});