Warn about nested renders
Andrew Clark committed
Feb 7, 2017 at 14:34 UTC
ebfde985d91b28c66d0a709144cce7223118c752
4 files changed
+24
-8
scripts/fiber/tests-passing-except-dev.txt
-3
@@ -105,9 +105,6 @@ src/renderers/__tests__/ReactComponentTreeHook-test.native.js
105
* reports update counts
106
* does not report top-level wrapper as a root
107
108
-src/renderers/__tests__/ReactCompositeComponent-test.js
109
-* should disallow nested render calls
110
-
108
src/renderers/__tests__/ReactHostOperationHistoryHook-test.js
109
* gets recorded for host roots
110
* gets recorded for composite roots
scripts/fiber/tests-passing.txt
+1
@@ -591,6 +591,7 @@ src/renderers/__tests__/ReactCompositeComponent-test.js
591
* should pass context when re-rendered
592
* unmasked context propagates through updates
593
* should trigger componentWillReceiveProps for context changes
594
+* should disallow nested render calls
595
* only renders once if updated in componentWillReceiveProps
596
* only renders once if updated in componentWillReceiveProps when batching
597
* should update refs if shouldComponentUpdate gives false
src/renderers/__tests__/ReactCompositeComponent-test.js
+5
-5
@@ -1028,11 +1028,11 @@ describe('ReactCompositeComponent', () => {
1028
1029
ReactTestUtils.renderIntoDocument(<Outer />);
1030
expectDev(console.error.calls.count()).toBe(1);
1031
- expectDev(console.error.calls.argsFor(0)[0]).toBe(
1032
- 'Warning: _renderNewRootComponent(): Render methods should ' +
1033
- 'be a pure function of props and state; triggering nested component ' +
1034
- 'updates from render is not allowed. If necessary, trigger nested ' +
1035
- 'updates in componentDidUpdate.\n\nCheck the render method of Outer.'
1031
+ expectDev(console.error.calls.argsFor(0)[0]).toMatch(
1032
+ 'Render methods should be a pure function of props and state; ' +
1033
+ 'triggering nested component updates from render is not allowed. If ' +
1034
+ 'necessary, trigger nested updates in componentDidUpdate.\n\nCheck the ' +
1035
+ 'render method of Outer.'
1036
);
1037
});
1038
src/renderers/shared/fiber/ReactFiberReconciler.js
+18
@@ -32,6 +32,9 @@ var ReactFiberScheduler = require('ReactFiberScheduler');
32
if (__DEV__) {
33
var warning = require('warning');
34
var ReactFiberInstrumentation = require('ReactFiberInstrumentation');
35
+ var warning = require('warning');
36
+ var ReactCurrentOwner = require('ReactCurrentOwner');
37
+ var { getComponentName } = require('ReactFiberTreeReflection');
38
}
39
40
var { findCurrentHostFiber } = require('ReactFiberTreeReflection');
@@ -144,6 +147,21 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
147
} = ReactFiberScheduler(config);
148
149
function scheduleTopLevelUpdate(current : Fiber, element : ReactNodeList, callback : ?Function) {
150
+ if (__DEV__) {
151
+ const owner = ReactCurrentOwner.current;
152
+ if (owner && typeof owner.tag === 'number') {
153
+ const ownerFiber : Fiber = (owner : any);
154
+ warning(
155
+ false,
156
+ 'Render methods should be a pure function of props and state; ' +
157
+ 'triggering nested component updates from render is not allowed. ' +
158
+ 'If necessary, trigger nested updates in componentDidUpdate.\n\n' +
159
+ 'Check the render method of %s.',
160
+ getComponentName(ownerFiber)
161
+ );
162
+ }
163
+ }
164
+
165
const priorityLevel = getPriorityContext();
166
const nextState = { element };
167
callback = callback === undefined ? null : callback;