Warn about isMounted inside render
Andrew Clark committed
Feb 7, 2017 at 11:48 UTC
4d52ebc0665068695bab91ac6c125f2502a6b64e
3 files changed
+29
-4
scripts/fiber/tests-passing-except-dev.txt
-2
@@ -1,6 +1,4 @@
1
src/renderers/__tests__/ReactComponentLifeCycle-test.js
2
-* should correctly determine if a component is mounted
3
-* should correctly determine if a null component is mounted
2
* warns if findDOMNode is used inside render
3
4
src/renderers/__tests__/ReactComponentTreeHook-test.js
scripts/fiber/tests-passing.txt
+2
@@ -547,6 +547,8 @@ src/renderers/__tests__/ReactComponentLifeCycle-test.js
547
* throws when accessing state in componentWillMount
548
* should allow update state inside of componentWillMount
549
* should not allow update state inside of getInitialState
550
+* should correctly determine if a component is mounted
551
+* should correctly determine if a null component is mounted
552
* isMounted should return false when unmounted
553
* should not throw when updating an auxiliary component
554
* should allow state updates in componentDidMount
src/renderers/shared/fiber/ReactFiberTreeReflection.js
+27
-2
@@ -15,13 +15,19 @@
15
import type { Fiber } from 'ReactFiber';
16
17
var ReactInstanceMap = require('ReactInstanceMap');
18
+var ReactCurrentOwner = require('ReactCurrentOwner');
19
20
var invariant = require('invariant');
21
22
+if (__DEV__) {
23
+ var warning = require('warning');
24
+}
25
+
26
var {
27
HostRoot,
28
HostComponent,
29
HostText,
30
+ ClassComponent,
31
} = require('ReactTypeOfWork');
32
33
var {
@@ -66,6 +72,24 @@ exports.isFiberMounted = function(fiber : Fiber) : boolean {
72
};
73
74
exports.isMounted = function(component : ReactComponent<any, any, any>) : boolean {
75
+ if (__DEV__) {
76
+ const owner = (ReactCurrentOwner.current : any);
77
+ if (owner !== null && owner.tag === ClassComponent) {
78
+ const ownerFiber : Fiber = owner;
79
+ const instance = ownerFiber.stateNode;
80
+ warning(
81
+ instance._warnedAboutRefsInRender,
82
+ '%s is accessing isMounted inside its render() function. ' +
83
+ 'render() should be a pure function of props and state. It should ' +
84
+ 'never access something that requires stale data from the previous ' +
85
+ 'render, such as refs. Move this logic to componentDidMount and ' +
86
+ 'componentDidUpdate instead.',
87
+ getComponentName(ownerFiber)
88
+ );
89
+ instance._warnedAboutRefsInRender = true;
90
+ }
91
+ }
92
+
93
var fiber : ?Fiber = ReactInstanceMap.get(component);
94
if (!fiber) {
95
return false;
@@ -243,7 +267,7 @@ exports.findCurrentHostFiber = function(parent : Fiber) : Fiber | null {
267
return null;
268
};
269
246
-exports.getComponentName = function(fiber: Fiber): string {
270
+function getComponentName(fiber: Fiber): string {
271
const type = fiber.type;
272
const instance = fiber.stateNode;
273
const constructor = instance && instance.constructor;
@@ -252,4 +276,5 @@ exports.getComponentName = function(fiber: Fiber): string {
276
type.name || (constructor && constructor.name) ||
277
'A Component'
278
);
255
-};
279
+}
280
+exports.getComponentName = getComponentName;