Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to resolve a react native EventEmitterListener warning

I am using a event emitter to communicate between a map component and the toolbar. Note* I am using this same code in other parts of my app without issue. The error I am getting is :

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.

I have tried to solve this by similar posts but it is not working. I thought it had to do with the mount && unmount methods in both components?

Toolbar Component

        componentDidMount() {
    this.showLocateIconListener = AppEventEmitter.addListener('isTrip', this.isTrip.bind(this));
    this.endTripListener = AppEventEmitter.addListener('showLocateIcon', this.showLocateIcon.bind(this));
    this.endSubdivisionIcon = AppEventEmitter.addListener('showSubdivisionIcon', this.showSubdivisionIcon.bind(this));
}

componentWillUnMount() {
    this.showLocateIconListener.remove();
    this.endTripListener.remove();
    this.endSubdivisionIcon.remove();
}


 //// this is where the error is happening
showSubdivisionIcon(val) {
    if (val != 0)
        this.setState({
            items: menuSubdivision,
            subdivisionId: val
        })
    else
        this.setState({
            items: menu
        })
}

Map component

  onMarkerPress(val) {
    AppEventEmitter.emit('showSubdivisionIcon', val.id);
}

The console error detail for the EventEmitter.js leads to this

  subscription.listener.apply(
        subscription.context,
        Array.prototype.slice.call(arguments, 1)
      );

Complete section in EventEmitter.js

      /**
   * Emits an event of the given type with the given data. All handlers of that
   * particular type will be notified.
   *
   * @param {string} eventType - Name of the event to emit
   * @param {...*} Arbitrary arguments to be passed to each registered listener
   *
   * @example
   *   emitter.addListener('someEvent', function(message) {
   *     console.log(message);
   *   });
   *
   *   emitter.emit('someEvent', 'abc'); // logs 'abc'
   */
  emit(eventType: String) {
    var subscriptions = this._subscriber.getSubscriptionsForType(eventType);
    if (subscriptions) {
      var keys = Object.keys(subscriptions);
      for (var ii = 0; ii < keys.length; ii++) {
        var key = keys[ii];
        var subscription = subscriptions[key];

        // The subscription may have been removed during this event loop.
        if (subscription) {
          this._currentSubscription = subscription;
          subscription.listener.apply(
            subscription.context,
            Array.prototype.slice.call(arguments, 1)
          );
        }
      }
      this._currentSubscription = null;
    }
  }
like image 881
texas697 Avatar asked May 19 '16 15:05

texas697


People also ask

How do I remove a listener from react native?

Add the event listener in the useEffect hook. Return a function from the useEffect hook. Use the removeEventListener method to remove the event listener when the component unmounts.

How do I get rid of addEventListener Appstate?

Use the remove() method on the EventSubscription returned by addEventListener() .

How do you use EventEmitter in react native?

Here is an example using EventEmitter : import { EventEmitter } from 'events'; const newEvent = new EventEmitter(); // then you can use: "emit", "on", "once", and "off" newEvent. on('example. event', () => { // ... });


1 Answers

The only problem is that your event listeners are not removed, because the name of the componentWillUnmount method is incorrect. In your code the M of mount is capital, where as it should be lowercase.

componentWillUnmount() {
    this.showLocateIconListener.remove();
    this.endTripListener.remove();
    this.endSubdivisionIcon.remove();
}
like image 153
egergo Avatar answered Nov 02 '22 04:11

egergo