@samitouri / QOS-React-2 / commits / b3d8c5376f

[RN] Remove isMounted() false positive warning (#13511)

Dan Abramov committed Aug 30, 2018 at 18:42 UTC b3d8c5376f1e0510963262d26e5029a9c463922f
5 files changed +53 -31
packages/react-native-renderer/src/NativeMethodsMixin.js
+5 -5
@@ -22,7 +22,7 @@ import UIManager from 'UIManager';
22
23 import * as ReactNativeAttributePayload from './ReactNativeAttributePayload';
24 import {
25 - mountSafeCallback,
25 + mountSafeCallback_NOT_REALLY_SAFE,
26 throwOnStylesProp,
27 warnForStyleProps,
28 } from './NativeMethodsMixinUtils';
@@ -67,7 +67,7 @@ export default function(
67 measure: function(callback: MeasureOnSuccessCallback) {
68 UIManager.measure(
69 findNodeHandle(this),
70 - mountSafeCallback(this, callback),
70 + mountSafeCallback_NOT_REALLY_SAFE(this, callback),
71 );
72 },
73
@@ -89,7 +89,7 @@ export default function(
89 measureInWindow: function(callback: MeasureInWindowOnSuccessCallback) {
90 UIManager.measureInWindow(
91 findNodeHandle(this),
92 - mountSafeCallback(this, callback),
92 + mountSafeCallback_NOT_REALLY_SAFE(this, callback),
93 );
94 },
95
@@ -109,8 +109,8 @@ export default function(
109 UIManager.measureLayout(
110 findNodeHandle(this),
111 relativeToNativeNode,
112 - mountSafeCallback(this, onFail),
113 - mountSafeCallback(this, onSuccess),
112 + mountSafeCallback_NOT_REALLY_SAFE(this, onFail),
113 + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess),
114 );
115 },
116
packages/react-native-renderer/src/NativeMethodsMixinUtils.js
+21 -11
@@ -11,26 +11,36 @@
11 * In the future, we should cleanup callbacks by cancelling them instead of
12 * using this.
13 */
14 -export function mountSafeCallback(context: any, callback: ?Function): any {
14 +export function mountSafeCallback_NOT_REALLY_SAFE(
15 + context: any,
16 + callback: ?Function,
17 +): any {
18 return function() {
19 if (!callback) {
20 return undefined;
21 }
22 + // This protects against createClass() components.
23 + // We don't know if there is code depending on it.
24 + // We intentionally don't use isMounted() because even accessing
25 + // isMounted property on a React ES6 class will trigger a warning.
26 if (typeof context.__isMounted === 'boolean') {
20 - // TODO(gaearon): this is gross and should be removed.
21 - // It is currently necessary because View uses createClass,
22 - // and so any measure() calls on View (which are done by React
23 - // DevTools) trigger the isMounted() deprecation warning.
27 if (!context.__isMounted) {
28 return undefined;
29 }
27 - // The else branch is important so that we don't
28 - // trigger the deprecation warning by calling isMounted.
29 - } else if (typeof context.isMounted === 'function') {
30 - if (!context.isMounted()) {
31 - return undefined;
32 - }
30 }
31 +
32 + // FIXME: there used to be other branches that protected
33 + // against unmounted host components. But RN host components don't
34 + // define isMounted() anymore, so those checks didn't do anything.
35 +
36 + // They caused false positive warning noise so we removed them:
37 + // https://github.com/facebook/react-native/issues/18868#issuecomment-413579095
38 +
39 + // However, this means that the callback is NOT guaranteed to be safe
40 + // for host components. The solution we should implement is to make
41 + // UIManager.measure() and similar calls truly cancelable. Then we
42 + // can change our own code calling them to cancel when something unmounts.
43 +
44 return callback.apply(context, arguments);
45 };
46 }
packages/react-native-renderer/src/ReactFabricHostConfig.js
+11 -5
@@ -15,7 +15,10 @@ import type {
15 ReactNativeBaseComponentViewConfig,
16 } from './ReactNativeTypes';
17
18 -import {mountSafeCallback, warnForStyleProps} from './NativeMethodsMixinUtils';
18 +import {
19 + mountSafeCallback_NOT_REALLY_SAFE,
20 + warnForStyleProps,
21 +} from './NativeMethodsMixinUtils';
22 import * as ReactNativeAttributePayload from './ReactNativeAttributePayload';
23 import * as ReactNativeFrameScheduling from './ReactNativeFrameScheduling';
24 import * as ReactNativeViewConfigRegistry from 'ReactNativeViewConfigRegistry';
@@ -104,13 +107,16 @@ class ReactFabricHostComponent {
107 }
108
109 measure(callback: MeasureOnSuccessCallback) {
107 - UIManager.measure(this._nativeTag, mountSafeCallback(this, callback));
110 + UIManager.measure(
111 + this._nativeTag,
112 + mountSafeCallback_NOT_REALLY_SAFE(this, callback),
113 + );
114 }
115
116 measureInWindow(callback: MeasureInWindowOnSuccessCallback) {
117 UIManager.measureInWindow(
118 this._nativeTag,
113 - mountSafeCallback(this, callback),
119 + mountSafeCallback_NOT_REALLY_SAFE(this, callback),
120 );
121 }
122
@@ -122,8 +128,8 @@ class ReactFabricHostComponent {
128 UIManager.measureLayout(
129 this._nativeTag,
130 relativeToNativeNode,
125 - mountSafeCallback(this, onFail),
126 - mountSafeCallback(this, onSuccess),
131 + mountSafeCallback_NOT_REALLY_SAFE(this, onFail),
132 + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess),
133 );
134 }
135
packages/react-native-renderer/src/ReactNativeComponent.js
+5 -5
@@ -22,7 +22,7 @@ import TextInputState from 'TextInputState';
22 import UIManager from 'UIManager';
23
24 import * as ReactNativeAttributePayload from './ReactNativeAttributePayload';
25 -import {mountSafeCallback} from './NativeMethodsMixinUtils';
25 +import {mountSafeCallback_NOT_REALLY_SAFE} from './NativeMethodsMixinUtils';
26
27 export default function(
28 findNodeHandle: any => ?number,
@@ -82,7 +82,7 @@ export default function(
82 measure(callback: MeasureOnSuccessCallback): void {
83 UIManager.measure(
84 findNodeHandle(this),
85 - mountSafeCallback(this, callback),
85 + mountSafeCallback_NOT_REALLY_SAFE(this, callback),
86 );
87 }
88
@@ -102,7 +102,7 @@ export default function(
102 measureInWindow(callback: MeasureInWindowOnSuccessCallback): void {
103 UIManager.measureInWindow(
104 findNodeHandle(this),
105 - mountSafeCallback(this, callback),
105 + mountSafeCallback_NOT_REALLY_SAFE(this, callback),
106 );
107 }
108
@@ -120,8 +120,8 @@ export default function(
120 UIManager.measureLayout(
121 findNodeHandle(this),
122 relativeToNativeNode,
123 - mountSafeCallback(this, onFail),
124 - mountSafeCallback(this, onSuccess),
123 + mountSafeCallback_NOT_REALLY_SAFE(this, onFail),
124 + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess),
125 );
126 }
127
packages/react-native-renderer/src/ReactNativeFiberHostComponent.js
+11 -5
@@ -21,7 +21,10 @@ import TextInputState from 'TextInputState';
21 import UIManager from 'UIManager';
22
23 import * as ReactNativeAttributePayload from './ReactNativeAttributePayload';
24 -import {mountSafeCallback, warnForStyleProps} from './NativeMethodsMixinUtils';
24 +import {
25 + mountSafeCallback_NOT_REALLY_SAFE,
26 + warnForStyleProps,
27 +} from './NativeMethodsMixinUtils';
28
29 /**
30 * This component defines the same methods as NativeMethodsMixin but without the
@@ -50,13 +53,16 @@ class ReactNativeFiberHostComponent {
53 }
54
55 measure(callback: MeasureOnSuccessCallback) {
53 - UIManager.measure(this._nativeTag, mountSafeCallback(this, callback));
56 + UIManager.measure(
57 + this._nativeTag,
58 + mountSafeCallback_NOT_REALLY_SAFE(this, callback),
59 + );
60 }
61
62 measureInWindow(callback: MeasureInWindowOnSuccessCallback) {
63 UIManager.measureInWindow(
64 this._nativeTag,
59 - mountSafeCallback(this, callback),
65 + mountSafeCallback_NOT_REALLY_SAFE(this, callback),
66 );
67 }
68
@@ -68,8 +74,8 @@ class ReactNativeFiberHostComponent {
74 UIManager.measureLayout(
75 this._nativeTag,
76 relativeToNativeNode,
71 - mountSafeCallback(this, onFail),
72 - mountSafeCallback(this, onSuccess),
77 + mountSafeCallback_NOT_REALLY_SAFE(this, onFail),
78 + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess),
79 );
80 }
81