Skip to content

react-timer-mixin throws errors in production (_setter is not a function) #20171

Closed
@danielgindi

Description

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);

img_98ed5f064199-1

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

  1. Create an empty react-native project.
  2. Put a <TextInput /> on the screen
  3. Run on device (from Xcode)
  4. Make sure that the Metro packager is shut down.
  5. Kill the app on the device, then run it again.
  6. Now it should say "Loading from pre-bundled file...". Fortunately, that pre-bundled file has not been uglified.
  7. It should immediately crash.

Metadata

Assignees

No one assigned

    Labels

    StaleThere has been a lack of activity on this issue and it may be closed soon.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions