@samitouri / QOS-React-2 / commits / 382be4e9e9

Improve error for nested render calls

In the future we could consider wrapping the entire public API (renderComponent, setProps, setState, etc) in this check but this should do for now. Test Plan: grunt test

Ben Alpert committed Apr 12, 2014 at 15:32 UTC 382be4e9e99e523f2e42dc1734e8a97a56e2b1e4
2 files changed +34
src/core/ReactCompositeComponent.js
+11
@@ -1164,6 +1164,17 @@ var ReactCompositeComponentMixin = {
1164 'ReactCompositeComponent',
1165 '_renderValidatedComponent',
1166 function() {
1167 + // We set ReactCurrentOwner.current back to null at the end of this
1168 + // function, so it should be null right now. If it's not, later code may
1169 + // give confusing errors.
1170 + invariant(
1171 + ReactCurrentOwner.current == null,
1172 + '%s.render(): Render methods should be a pure function of props and ' +
1173 + 'state; triggering nested component updates from render is not ' +
1174 + 'allowed. If necessary, trigger nested updates in ' +
1175 + 'componentDidUpdate.',
1176 + this.constructor.displayName || 'ReactCompositeComponent'
1177 + );
1178 var renderedComponent;
1179 var previousContext = ReactContext.current;
1180 ReactContext.current = this._processChildContext(
src/core/__tests__/ReactCompositeComponent-test.js
+23
@@ -1345,4 +1345,27 @@ describe('ReactCompositeComponent', function() {
1345 expect(console.warn.argsForCall.length).toBe(0);
1346 });
1347
1348 + it('should disallow nested render calls', function() {
1349 + var Inner = React.createClass({
1350 + render: function() {
1351 + return <div />;
1352 + }
1353 + });
1354 + var Outer = React.createClass({
1355 + render: function() {
1356 + ReactTestUtils.renderIntoDocument(<Inner />);
1357 + return <div />;
1358 + }
1359 + });
1360 +
1361 + expect(() => {
1362 + ReactTestUtils.renderIntoDocument(<Outer />);
1363 + }).toThrow(
1364 + 'Invariant Violation: Inner.render(): Render methods should be a pure ' +
1365 + 'function of props and state; triggering nested component updates ' +
1366 + 'from render is not allowed. If necessary, trigger nested updates in ' +
1367 + 'componentDidUpdate.'
1368 + );
1369 + });
1370 +
1371 });