From 0e8c3ff463420cc24f3bcc225cb9b0b76dd8eb3b Mon Sep 17 00:00:00 2001 From: Rahul Jiresal Date: Tue, 24 May 2016 11:41:33 -0700 Subject: [PATCH] =?UTF-8?q?Add=20a=20removeListener=20method=20to=20Device?= =?UTF-8?q?EventEmitter=20for=20Framework=20consi=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: The Framework is inconsistent in how listeners are removed in certain classes. This issue has been discussed in https://github.com/facebook/react-native/issues/6493. For example, **DeviceEventEmitter** ```javascript /* Current */ this.keyboardHideObserver = DeviceEventEmitter.addListener('keyboardWillHide', this.keyboardWillHide); this.keyboardHideObserver.remove(); /* Expected (maybe in addition to the current API) */ DeviceEventEmitter.addListener('keyboardWillHide', this.keyboardWillHide); DeviceEventEmitter.removeListener('keyboardWillHide', this.keyboardWillHide); ``` **AppStateIOS** ```javascript AppStateIOS.addEventListener('change', this.handleAppStateChange); AppStateIOS.removeEventListener('change', this.handleAppStateChange); ``` The API should be consistent, and preferably should allow both ways of removing the listeners. Currently, developers who tried to use the second way of removing the listeners get an error for function not found. Due to the lack of documenta Closes https://github.com/facebook/react-native/pull/6884 Differential Revision: D3341235 Pulled By: nicklockwood fbshipit-source-id: 87431e8b667f46ad002d4a6e3ca07cbc1e6b4007 --- Libraries/EventEmitter/EventEmitter.js | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Libraries/EventEmitter/EventEmitter.js b/Libraries/EventEmitter/EventEmitter.js index 2745cdda0..4a6789880 100644 --- a/Libraries/EventEmitter/EventEmitter.js +++ b/Libraries/EventEmitter/EventEmitter.js @@ -185,6 +185,34 @@ class EventEmitter { this._currentSubscription = null; } } + + /** + * Removes the given listener for event of specific type. + * + * @param {string} eventType - Name of the event to emit + * @param {function} listener - Function to invoke when the specified event is + * emitted + * + * @example + * emitter.removeListener('someEvent', function(message) { + * console.log(message); + * }); // removes the listener if already registered + * + */ + removeListener(eventType: String, listener) { + const subscriptions: ?[EmitterSubscription] = (this._subscriber.getSubscriptionsForType(eventType): any); + if (subscriptions) { + for (let i = 0, l = subscriptions.length; i < l; i++) { + const subscription = subscriptions[i]; + + // The subscription may have been removed during this event loop. + // its listener matches the listener in method parameters + if (subscription && subscription.listener === listener) { + subscription.remove(); + } + } + } + } } module.exports = EventEmitter;