Enable module pattern.
jim committed
Feb 9, 2016 at 12:07 UTC
428ef03bbba526032defe2a60252e9e0ca0d15e4
4 files changed
+52
-11
src/renderers/shared/reconciler/ReactCompositeComponent.js
+32
-6
@@ -44,16 +44,20 @@ function StatelessComponent(Component) {
44
StatelessComponent.prototype.render = function() {
45
var Component = ReactInstanceMap.get(this)._currentElement.type;
46
var element = Component(this.props, this.context, this.updater);
47
+ warnIfInvalidElement(Component, element);
48
+ return element;
49
+};
50
+
51
+function warnIfInvalidElement(Component, element) {
52
if (__DEV__) {
53
warning(
54
element === null || element === false || ReactElement.isValidElement(element),
50
- '%s must be a class extending React.Component or be a stateless ' +
51
- 'function that returns a valid React element.',
55
+ '%s(...): A valid React element (or null) must be returned. You may have ' +
56
+ 'returned undefined, an array or some other invalid object.',
57
Component.displayName || Component.name || 'Component'
58
);
59
}
55
- return element;
56
-};
60
+}
61
62
/**
63
* ------------------ The Life-Cycle of a Composite Component ------------------
@@ -168,7 +172,29 @@ var ReactCompositeComponentMixin = {
172
inst = new Component(publicProps, publicContext, ReactUpdateQueue);
173
}
174
} else {
171
- inst = new StatelessComponent(Component);
175
+ if (__DEV__) {
176
+ ReactCurrentOwner.current = this;
177
+ try {
178
+ inst = Component(publicProps, publicContext, ReactUpdateQueue);
179
+ } finally {
180
+ ReactCurrentOwner.current = null;
181
+ }
182
+ } else {
183
+ inst = Component(publicProps, publicContext, ReactUpdateQueue);
184
+ }
185
+ if (inst == null || inst.render == null) {
186
+ renderedElement = inst;
187
+ warnIfInvalidElement(Component, renderedElement);
188
+ invariant(
189
+ inst === null ||
190
+ inst === false ||
191
+ ReactElement.isValidElement(inst),
192
+ '%s(...): A valid React element (or null) must be returned. You may have ' +
193
+ 'returned undefined, an array or some other invalid object.',
194
+ Component.displayName || Component.name || 'Component'
195
+ );
196
+ inst = new StatelessComponent(Component);
197
+ }
198
}
199
200
if (__DEV__) {
@@ -869,7 +895,7 @@ var ReactCompositeComponentMixin = {
895
// TODO: An `isValidNode` function would probably be more appropriate
896
renderedComponent === null || renderedComponent === false ||
897
ReactElement.isValidElement(renderedComponent),
872
- '%s.render(): A valid ReactComponent must be returned. You may have ' +
898
+ '%s.render(): A valid React element (or null) must be returned. You may have ' +
899
'returned undefined, an array or some other invalid object.',
900
this.getName() || 'ReactCompositeComponent'
901
);
src/renderers/shared/reconciler/__tests__/ReactCompositeComponent-test.js
+15
@@ -72,6 +72,21 @@ describe('ReactCompositeComponent', function() {
72
spyOn(console, 'error');
73
});
74
75
+ it('should support module pattern components', function() {
76
+ function Child({test}) {
77
+ return {
78
+ render() {
79
+ return <div>{test}</div>;
80
+ },
81
+ };
82
+ }
83
+
84
+ var el = document.createElement('div');
85
+ ReactDOM.render(<Child test="test" />, el);
86
+
87
+ expect(el.textContent).toBe('test');
88
+ });
89
+
90
it('should support rendering to different child types over time', function() {
91
var instance = <MorphingComponent />;
92
instance = ReactTestUtils.renderIntoDocument(instance);
src/renderers/shared/reconciler/__tests__/ReactEmptyComponent-test.js
+1
-1
@@ -79,7 +79,7 @@ describe('ReactEmptyComponent', function() {
79
expect(function() {
80
ReactTestUtils.renderIntoDocument(<Component />);
81
}).toThrow(
82
- 'Component.render(): A valid ReactComponent must be returned. You may ' +
82
+ 'Component.render(): A valid React element (or null) must be returned. You may ' +
83
'have returned undefined, an array or some other invalid object.'
84
);
85
});
src/renderers/shared/reconciler/__tests__/ReactStatelessComponent-test.js
+4
-4
@@ -108,8 +108,8 @@ describe('ReactStatelessComponent', function() {
108
}).toThrow();
109
expect(console.error.calls.length).toBe(1);
110
expect(console.error.argsForCall[0][0]).toContain(
111
- 'NotAComponent must be a class extending React.Component or be a stateless ' +
112
- 'function that returns a valid React element.'
111
+ 'NotAComponent(...): A valid React element (or null) must be returned. '+
112
+ 'You may have returned undefined, an array or some other invalid object.'
113
);
114
});
115
@@ -238,8 +238,8 @@ describe('ReactStatelessComponent', function() {
238
}).toThrow(); // has no method 'render'
239
expect(console.error.calls.length).toBe(1);
240
expect(console.error.argsForCall[0][0]).toContain(
241
- 'Warning: NotAComponent must be a class extending React.Component or be a stateless ' +
242
- 'function that returns a valid React element.'
241
+ 'NotAComponent(...): A valid React element (or null) must be returned. You may ' +
242
+ 'have returned undefined, an array or some other invalid object.'
243
);
244
});
245
});