react-timer-mixin
throws errors in production (_setter is not a function) #20171
Description
- Review the documentation: https://facebook.github.io/react-native
- Search for existing issues: https://github.com/facebook/react-native/issues
- Use the latest React Native release: https://github.com/facebook/react-native/releases
Environment
React Native Environment Info:
System:
OS: macOS High Sierra 10.13.5
CPU: x64 Intel(R) Core(TM) i5-5287U CPU @ 2.90GHz
Memory: 209.75 MB / 8.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 10.6.0 - /usr/local/bin/node
npm: 6.1.0 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
IDEs:
Android Studio: 3.1 AI-173.4819257
Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
npmPackages:
react: ^16.4.1 => 16.4.1
react-native: ^0.56.0 => 0.56.0
npmGlobalPackages:
create-react-native-app: 1.0.0
react-native-cli: 2.0.1
Description
When bundling for release on iOS, many some elements crash the app by just being there.
An error report gave an unreadable junk, but I managed to reproduce it on a "debug" version with full stack trace.
TypeError: _setter is not a function. (In _setter(function() {
_clearer.call(this, id);
callback.apply(this, arguments);
}.bind(this), delta)', '_setter' is undefined)
This error is located at:
in TextInput (at Login.js:304)
react-timer-mixin
is loaded in ListView
, TextInput
, TouchableWithoutFeedback
.
Now react-timer-mixin
tries to wrap timing functions. I thought that because setImmediate
which specifically isn't available on iOS Safari, maybe it's failing on that, but it doesn't.
I managed to print out some data, pointing out that setImmediate
is available, and requestAnimationFrame
as well.
The function in react-timer-mixin
is this:
var setter = function(_setter, _clearer, array) {
return function(callback, delta) {
var id = _setter(function() {
_clearer.call(this, id);
callback.apply(this, arguments);
}.bind(this), delta);
if (!this[array]) {
this[array] = [id];
} else {
this[array].push(id);
}
return id;
};
};
and there are 4 calls to it:
var _setTimeout = setter(GLOBAL.setTimeout, _clearTimeout, _timeouts);
var _setInterval = setter(GLOBAL.setInterval, function() {/* noop */}, _intervals);
var _setImmediate = setter(GLOBAL.setImmediate, _clearImmediate, _immediates);
var _requestAnimationFrame = setter(GLOBAL.requestAnimationFrame, _cancelAnimationFrame, _rafs);
Reproducible Demo
Let us know how to reproduce the issue. Include a code sample, share a project, or share an app that reproduces the issue using https://snack.expo.io/. Please follow the guidelines for providing a
- Create an empty react-native project.
- Put a
<TextInput />
on the screen - Run on device (from Xcode)
- Make sure that the Metro packager is shut down.
- Kill the app on the device, then run it again.
- Now it should say "Loading from pre-bundled file...". Fortunately, that pre-bundled file has not been uglified.
- It should immediately crash.