Constructor error message (#11395)
* Constructor test and fix complete * Linters and prettier run * Remove unnecessary checks * Update error message * Updat unit test * prettier * Tweak the check to be more specific * Move tests to ReactCompositeComponent-test * add error call count and remove line
Dean Brophy committed
Nov 1, 2017 at 15:01 UTC
787c2ad2d97d001f35757877abd623c9a6b87afd
2 files changed
+58
-6
packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
+39
@@ -1533,4 +1533,43 @@ describe('ReactCompositeComponent', () => {
1533
ReactTestUtils.renderIntoDocument(<Component />);
1534
expect(mockArgs.length).toEqual(0);
1535
});
1536
+
1537
+ it('should return a meaningful warning when constructor is returned', () => {
1538
+ spyOn(console, 'error');
1539
+ class RenderTextInvalidConstructor extends React.Component {
1540
+ constructor(props) {
1541
+ super(props);
1542
+ return {something: false};
1543
+ }
1544
+
1545
+ render() {
1546
+ return <div />;
1547
+ }
1548
+ }
1549
+
1550
+ expect(function() {
1551
+ ReactTestUtils.renderIntoDocument(<RenderTextInvalidConstructor />);
1552
+ }).toThrow();
1553
+
1554
+ expectDev(console.error.calls.count()).toBe(1);
1555
+ expectDev(console.error.calls.mostRecent().args[0]).toBe(
1556
+ 'Warning: RenderTextInvalidConstructor(...): No `render` method found on the returned component instance: ' +
1557
+ 'did you accidentally return an object from the constructor?',
1558
+ );
1559
+ });
1560
+
1561
+ it('should return error if render is not defined', () => {
1562
+ spyOn(console, 'error');
1563
+ class RenderTestUndefinedRender extends React.Component {}
1564
+
1565
+ expect(function() {
1566
+ ReactTestUtils.renderIntoDocument(<RenderTestUndefinedRender />);
1567
+ }).toThrow();
1568
+
1569
+ expectDev(console.error.calls.count()).toBe(1);
1570
+ expectDev(console.error.calls.mostRecent().args[0]).toBe(
1571
+ 'Warning: RenderTestUndefinedRender(...): No `render` method found on the returned ' +
1572
+ 'component instance: you may have forgotten to define `render`.',
1573
+ );
1574
+ });
1575
});
packages/react-reconciler/src/ReactFiberClassComponent.js
+19
-6
@@ -202,12 +202,25 @@ module.exports = function(
202
if (__DEV__) {
203
const name = getComponentName(workInProgress);
204
const renderPresent = instance.render;
205
- warning(
206
- renderPresent,
207
- '%s(...): No `render` method found on the returned component ' +
208
- 'instance: you may have forgotten to define `render`.',
209
- name,
210
- );
205
+
206
+ if (!renderPresent) {
207
+ if (type.prototype && typeof type.prototype.render === 'function') {
208
+ warning(
209
+ false,
210
+ '%s(...): No `render` method found on the returned component ' +
211
+ 'instance: did you accidentally return an object from the constructor?',
212
+ name,
213
+ );
214
+ } else {
215
+ warning(
216
+ false,
217
+ '%s(...): No `render` method found on the returned component ' +
218
+ 'instance: you may have forgotten to define `render`.',
219
+ name,
220
+ );
221
+ }
222
+ }
223
+
224
const noGetInitialStateOnES6 =
225
!instance.getInitialState ||
226
instance.getInitialState.isReactClassApproved ||