Quantcast
Channel: Active questions tagged react-native+ios - Stack Overflow
Viewing all articles
Browse latest Browse all 16750

React Native ~0.61.4 Event Emitter causing crash on IOS?

$
0
0

I am building a Music App where the mini player component holds the expo audio instance and it is separated from the bottom tab navigator for two important reasons :

1 - The audio instance lives in that mini-player component so navigation won't reset it.

2 - The mini player is global thus available in all application stack and tab navigations.

I am using NativeEventEmitter to help me control the player actions (ie: Play/Pause;Next; Pervious;) since those function lives in that mini-player component and needs to be called from a stack screen inside the tab navigator ! .

Now in Android it is working fine but in IOS, it is causing the application to crash.

The error :

Native Module cannot be null
- node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:36:16 in App/Containers/Player/PlayerScreen.js:47:4 in _handleStop

The Logic I am implementing here , is upon clicking on the miniPlayer component after it is mounted, I am hiding it and navigating to the Player Screen;

Player Screen :

...
class PlayerScreen extends Component {
  constructor(props) {
    super(props);
    this.eventEmitter = new NativeEventEmitter();
    this._handleNext = this._handleNext.bind(this);
    this._handlePlayPause = this._handlePlayPause.bind(this);
    this._handlePrevious = this._handlePrevious.bind(this);
    this.state = {
      time: "00:00"
    };
  }

  componentDidMount() {

  }

  _handlePlayPause = () => {
    this.eventEmitter.emit("PLAYPAUSE", "");
  };

  _handleNext = () => {
    this.eventEmitter.emit("NEXTSONG", "");
  };

  _handlePrevious = () => {
    this.eventEmitter.emit("PREVIOUSSONG", "");
  };

  _handleStop = () => {
    this.eventEmitter.emit("STOPSONG", "");
  };
...
render()
....

MiniPlayer Component :

componentDidMount() {
    this.listener = DeviceEventEmitter.addListener("PLAYPAUSE", data => {
      this._handlePlayAndPause();
      console.log("New Event is registered At Listeners PLAY_PAUSE");

    });
    this.listenerN = DeviceEventEmitter.addListener("NEXTSONG", data => {
      this._handleNextSong()
      console.log("New Event is registered At Listeners NEXT_SONG ");

    });
    this.listenerP = DeviceEventEmitter.addListener("PREVIOUSSONG", data => {
     this._handlePreviousSong()
      console.log("New Event is registered At Listeners PREVIOUS_SONG");

    });

    this.listenerS = DeviceEventEmitter.addListener("STOPSONG", data => {
      this._handleStopSong();
      console.log("New Event is registered At Listeners STOPSONG");
    }) 

According the some article on Medium:

React Native no longer include the Node Standard Library. However, there are standalone modules which have reimplemented the EventEmitter API.

While looking at the NativeEventEmitter.js Abstract base class, I can see this at the constructor.

const EventEmitter = require('../vendor/emitter/EventEmitter');
const Platform = require('../Utilities/Platform');
const RCTDeviceEventEmitter = require('./RCTDeviceEventEmitter');

const invariant = require('invariant');

...

class NativeEventEmitter extends EventEmitter {
  _nativeModule: ?NativeModule;

  constructor(nativeModule: ?NativeModule) {
    super(RCTDeviceEventEmitter.sharedSubscriber);
    if (Platform.OS === 'ios') {
      invariant(nativeModule, 'Native module cannot be null.'); <== This where it crashes
      this._nativeModule = nativeModule;
    }
  }

Update :

I have created a snack with two component that reproduce what I am trying to achieve :

https://snack.expo.io/@git/github.com/oflarcade/customEventsExpo

on Android it is working fine / on IOS :

enter image description here


Viewing all articles
Browse latest Browse all 16750

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>