From 035718ba97bb44c68f2a4ccdd95e537e3d28690c Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Wed, 10 Mar 2021 16:02:48 -0800 Subject: [PATCH] RN: Restore Deprecated Event Methods Summary: Restore deprecated event listener removal methods in order to minimize breaking changes for the next release. The methods will work, but they will not report a warning via `console.error`. Changelog: [General][Added] - `EventEmitter.removeListener` now emits a deprecation notice. [General][Added] - Restored `AppState.removeEventListener` with a deprecation notice. [General][Added] - Restored `Keyboard.removeEventListener` with a deprecation notice. [General][Added] - Restored `Linking.removeEventListener` with a deprecation notice. Reviewed By: nadiia, kacieb Differential Revision: D26589441 fbshipit-source-id: 7d89982a182cf2163136e157d4c1beee91c30393 --- Libraries/AppState/AppState.js | 33 ++++++++++++++++++++ Libraries/Components/Keyboard/Keyboard.js | 11 +++++++ Libraries/EventEmitter/NativeEventEmitter.js | 13 ++++++++ Libraries/Linking/Linking.js | 11 +++++++ Libraries/vendor/emitter/_EventEmitter.js | 20 +++++------- 5 files changed, 75 insertions(+), 13 deletions(-) diff --git a/Libraries/AppState/AppState.js b/Libraries/AppState/AppState.js index 4668efc4ecd3cc..3f072015e76108 100644 --- a/Libraries/AppState/AppState.js +++ b/Libraries/AppState/AppState.js @@ -123,6 +123,39 @@ class AppState { } throw new Error('Trying to subscribe to unknown event: ' + type); } + + /** + * @deprecated Use `remove` on the EventSubscription from `addEventListener`. + */ + removeEventListener>( + type: K, + listener: (...$ElementType) => mixed, + ): void { + const emitter = this._emitter; + if (emitter == null) { + throw new Error('Cannot use AppState when `isAvailable` is false.'); + } + // NOTE: This will report a deprecation notice via `console.error`. + switch (type) { + case 'change': + // $FlowIssue[invalid-tuple-arity] Flow cannot refine handler based on the event type + // $FlowIssue[incompatible-call] + emitter.removeListener('appStateDidChange', listener); + return; + case 'memoryWarning': + // $FlowIssue[invalid-tuple-arity] Flow cannot refine handler based on the event type + // $FlowIssue[incompatible-call] + emitter.removeListener('memoryWarning', listener); + return; + case 'blur': + case 'focus': + // $FlowIssue[invalid-tuple-arity] Flow cannot refine handler based on the event type + // $FlowIssue[incompatible-call] + emitter.addListener('appStateFocusChange', listener); + return; + } + throw new Error('Trying to unsubscribe from unknown event: ' + type); + } } module.exports = (new AppState(): AppState); diff --git a/Libraries/Components/Keyboard/Keyboard.js b/Libraries/Components/Keyboard/Keyboard.js index db52a90e31a512..46f95c771c2f4b 100644 --- a/Libraries/Components/Keyboard/Keyboard.js +++ b/Libraries/Components/Keyboard/Keyboard.js @@ -137,6 +137,17 @@ class Keyboard { return this._emitter.addListener(eventType, listener); } + /** + * @deprecated Use `remove` on the EventSubscription from `addEventListener`. + */ + removeEventListener>( + eventType: K, + listener: (...$ElementType) => mixed, + ): void { + // NOTE: This will report a deprecation notice via `console.error`. + this._emitter.removeListener(eventType, listener); + } + /** * Removes all listeners for a specific event type. * diff --git a/Libraries/EventEmitter/NativeEventEmitter.js b/Libraries/EventEmitter/NativeEventEmitter.js index 41d728262f40b4..42c9c703ca5b2e 100644 --- a/Libraries/EventEmitter/NativeEventEmitter.js +++ b/Libraries/EventEmitter/NativeEventEmitter.js @@ -74,6 +74,19 @@ export default class NativeEventEmitter }; } + /** + * @deprecated Use `remove` on the EventSubscription from `addListener`. + */ + removeListener>( + eventType: TEvent, + listener: (...args: $ElementType) => mixed, + ): void { + this._nativeModule?.removeListeners(1); + // NOTE: This will report a deprecation notice via `console.error`. + // $FlowFixMe[prop-missing] - `removeListener` exists but is deprecated. + RCTDeviceEventEmitter.removeListener(eventType, listener); + } + emit>( eventType: TEvent, ...args: $ElementType diff --git a/Libraries/Linking/Linking.js b/Libraries/Linking/Linking.js index 6acc9be2bb3883..e69e07a4c53b2c 100644 --- a/Libraries/Linking/Linking.js +++ b/Libraries/Linking/Linking.js @@ -46,6 +46,17 @@ class Linking extends NativeEventEmitter { return this.addListener(eventType, listener); } + /** + * @deprecated Use `remove` on the EventSubscription from `addEventListener`. + */ + removeEventListener>( + eventType: K, + listener: (...$ElementType) => mixed, + ): void { + // NOTE: This will report a deprecation notice via `console.error`. + this.removeListener(eventType, listener); + } + /** * Try to open the given `url` with any of the installed apps. * diff --git a/Libraries/vendor/emitter/_EventEmitter.js b/Libraries/vendor/emitter/_EventEmitter.js index 908499ec636113..24528174a51d01 100644 --- a/Libraries/vendor/emitter/_EventEmitter.js +++ b/Libraries/vendor/emitter/_EventEmitter.js @@ -97,8 +97,7 @@ class EventEmitter } /** - * Removes a specific subscription. Called by the `remove()` method of the - * subscription itself to ensure any necessary cleanup is performed. + * @deprecated Use `remove` on the EventSubscription from `addListener`. */ removeSubscription>( subscription: EmitterSubscription, @@ -160,23 +159,18 @@ class EventEmitter } /** - * 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 - * + * @deprecated Use `remove` on the EventSubscription from `addListener`. */ removeListener>( eventType: K, // FIXME: listeners should return void instead of mixed to prevent issues listener: (...$ElementType) => mixed, ): void { + console.error( + `EventEmitter.removeListener('${eventType}', ...): Method has been ` + + 'deprecated. Please instead use `remove()` on the subscription ' + + 'returned by `EventEmitter.addListener`.', + ); const subscriptions = this._subscriber.getSubscriptionsForType(eventType); if (subscriptions) { for (let i = 0, l = subscriptions.length; i < l; i++) {