Fix ReferenceError when requestAnimationFrame isn't defined (#13152)
* Make the test fail * Fix rAF detection to avoid a ReferenceError
Dan Abramov committed
Jul 5, 2018 at 19:42 UTC
1386ccddd8cecc5979d79c0e9bbbd59373c6a2fc
2 files changed
+30
-16
packages/react-dom/src/__tests__/ReactDOM-test.js
+2
-2
@@ -434,10 +434,10 @@ describe('ReactDOM', () => {
434
}
435
});
436
437
- it('warns when requestAnimationFrame is not polyfilled in the browser', () => {
437
+ it('warns when requestAnimationFrame is not polyfilled', () => {
438
const previousRAF = global.requestAnimationFrame;
439
try {
440
- global.requestAnimationFrame = undefined;
440
+ delete global.requestAnimationFrame;
441
jest.resetModules();
442
expect(() => require('react-dom')).toWarnDev(
443
"This browser doesn't support requestAnimationFrame.",
packages/react-scheduler/src/ReactScheduler.js
+28
-14
@@ -44,18 +44,6 @@ export type CallbackIdType = CallbackConfigType;
44
import {canUseDOM} from 'shared/ExecutionEnvironment';
45
import warning from 'shared/warning';
46
47
-if (__DEV__) {
48
- if (canUseDOM && typeof requestAnimationFrame !== 'function') {
49
- warning(
50
- false,
51
- // TODO: reword this when schedule is a stand-alone module
52
- "This browser doesn't support requestAnimationFrame. " +
53
- 'Make sure that you load a ' +
54
- 'polyfill in older browsers. https://fb.me/react-polyfills',
55
- );
56
- }
57
-}
58
-
47
// We capture a local reference to any global, in case it gets polyfilled after
48
// this module is initially evaluated.
49
// We want to be using a consistent implementation.
@@ -64,12 +52,24 @@ const localDate = Date;
52
// This initialization code may run even on server environments
53
// if a component just imports ReactDOM (e.g. for findDOMNode).
54
// Some environments might not have setTimeout or clearTimeout.
55
+// However, we always expect them to be defined on the client.
56
// https://github.com/facebook/react/pull/13088
57
const localSetTimeout =
58
typeof setTimeout === 'function' ? setTimeout : (undefined: any);
59
const localClearTimeout =
60
typeof clearTimeout === 'function' ? clearTimeout : (undefined: any);
61
62
+// We don't expect either of these to necessarily be defined,
63
+// but we will error later if they are missing on the client.
64
+const localRequestAnimationFrame =
65
+ typeof requestAnimationFrame === 'function'
66
+ ? requestAnimationFrame
67
+ : (undefined: any);
68
+const localCancelAnimationFrame =
69
+ typeof cancelAnimationFrame === 'function'
70
+ ? cancelAnimationFrame
71
+ : (undefined: any);
72
+
73
const hasNativePerformanceNow =
74
typeof performance === 'object' && typeof performance.now === 'function';
75
@@ -123,8 +123,22 @@ if (!canUseDOM) {
123
localClearTimeout(timeoutId);
124
};
125
} else {
126
- const localRequestAnimationFrame = requestAnimationFrame;
127
- const localCancelAnimationFrame = cancelAnimationFrame;
126
+ if (typeof localRequestAnimationFrame !== 'function') {
127
+ warning(
128
+ false,
129
+ "This browser doesn't support requestAnimationFrame. " +
130
+ 'Make sure that you load a ' +
131
+ 'polyfill in older browsers. https://fb.me/react-polyfills',
132
+ );
133
+ }
134
+ if (typeof localCancelAnimationFrame !== 'function') {
135
+ warning(
136
+ false,
137
+ "This browser doesn't support cancelAnimationFrame. " +
138
+ 'Make sure that you load a ' +
139
+ 'polyfill in older browsers. https://fb.me/react-polyfills',
140
+ );
141
+ }
142
143
let headOfPendingCallbacksLinkedList: CallbackConfigType | null = null;
144
let tailOfPendingCallbacksLinkedList: CallbackConfigType | null = null;