Skip to content

Commit 787c2ad

Browse files
dylanapplegategaearon
authored andcommitted
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
1 parent 9d75a62 commit 787c2ad

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

packages/react-dom/src/__tests__/ReactCompositeComponent-test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,4 +1533,43 @@ describe('ReactCompositeComponent', () => {
15331533
ReactTestUtils.renderIntoDocument(<Component />);
15341534
expect(mockArgs.length).toEqual(0);
15351535
});
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+
});
15361575
});

packages/react-reconciler/src/ReactFiberClassComponent.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,25 @@ module.exports = function(
202202
if (__DEV__) {
203203
const name = getComponentName(workInProgress);
204204
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+
211224
const noGetInitialStateOnES6 =
212225
!instance.getInitialState ||
213226
instance.getInitialState.isReactClassApproved ||

0 commit comments

Comments
 (0)