mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #4859 from zpao/stateless-arrow-functions
Support native arrow functions as stateless components
This commit is contained in:
@@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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'
|
||||
);
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user