Skip to content

Commit 003d63d

Browse files
yungstersfacebook-github-bot
authored andcommitted
RN: Refactor AccessibilityInfo Listeners
Summary: Refactors `AccessibilityInfo` so that it does not reimplement the event listener logic that is already implemented in `EventEmitter` (which backs the implementation of `RCTDeviceEventEmitter`). This also means that calling `AccessibilityInfo.removeEventListener` will correctly display a deprecation error, due to `EventEmitter.removeListener` being deprecated. In a future release, both of these methods will be removed. Changelog: [General][Deprecated] - Deprecate `AccessibilityInfo.removeEventListener`. Reviewed By: kacieb Differential Revision: D27574340 fbshipit-source-id: 98c71d9c1470018df0f1526cc2f349aac842e786
1 parent 7ee2acc commit 003d63d

File tree

2 files changed

+57
-60
lines changed

2 files changed

+57
-60
lines changed

Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js

+25-24
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* @flow strict-local
99
*/
1010

11+
import type EventEmitter from '../../vendor/emitter/EventEmitter';
1112
import RCTDeviceEventEmitter from '../../EventEmitter/RCTDeviceEventEmitter';
1213
import NativeAccessibilityInfo from './NativeAccessibilityInfo';
1314
import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
@@ -28,8 +29,6 @@ type AccessibilityEventDefinitions = {
2829

2930
type AccessibilityEventTypes = 'focus' | 'click';
3031

31-
const _subscriptions = new Map();
32-
3332
/**
3433
* Sometimes it's useful to know whether or not the device has a screen reader
3534
* that is currently active. The `AccessibilityInfo` API is designed for this
@@ -106,43 +105,45 @@ const AccessibilityInfo = {
106105
eventName: K,
107106
handler: (...$ElementType<AccessibilityEventDefinitions, K>) => void,
108107
): EventSubscription {
109-
let listener;
110-
111108
if (eventName === 'change' || eventName === 'screenReaderChanged') {
112-
listener = RCTDeviceEventEmitter.addListener(
109+
return RCTDeviceEventEmitter.addListener(
113110
TOUCH_EXPLORATION_EVENT,
114111
handler,
115112
);
116-
} else if (eventName === 'reduceMotionChanged') {
117-
listener = RCTDeviceEventEmitter.addListener(
118-
REDUCE_MOTION_EVENT,
119-
handler,
120-
);
121113
}
122-
123-
// $FlowFixMe[escaped-generic]
124-
_subscriptions.set(handler, listener);
125-
114+
if (eventName === 'reduceMotionChanged') {
115+
return RCTDeviceEventEmitter.addListener(REDUCE_MOTION_EVENT, handler);
116+
}
126117
return {
127-
remove: () => {
128-
// $FlowIssue flow does not recognize handler properly
129-
AccessibilityInfo.removeEventListener<K>(eventName, handler);
118+
remove(): void {
119+
// Do nothing.
130120
},
131121
};
132122
},
133123

124+
/**
125+
* @deprecated Use `remove` on the EventSubscription from `addEventListener`.
126+
*/
134127
removeEventListener: function<K: $Keys<AccessibilityEventDefinitions>>(
135128
eventName: K,
136129
handler: (...$ElementType<AccessibilityEventDefinitions, K>) => void,
137130
): void {
138-
// $FlowFixMe[escaped-generic]
139-
const listener = _subscriptions.get(handler);
140-
if (!listener) {
141-
return;
131+
// NOTE: This will report a deprecation notice via `console.error`.
132+
if (eventName === 'change' || eventName === 'screenReaderChanged') {
133+
// $FlowIgnore[incompatible-cast]
134+
(RCTDeviceEventEmitter: EventEmitter<$FlowFixMe>).removeListener(
135+
TOUCH_EXPLORATION_EVENT,
136+
// $FlowFixMe[invalid-tuple-arity]
137+
handler,
138+
);
139+
} else if (eventName === 'reduceMotionChanged') {
140+
// $FlowIgnore[incompatible-cast]
141+
(RCTDeviceEventEmitter: EventEmitter<$FlowFixMe>).removeListener(
142+
REDUCE_MOTION_EVENT,
143+
// $FlowFixMe[invalid-tuple-arity]
144+
handler,
145+
);
142146
}
143-
listener.remove();
144-
// $FlowFixMe[escaped-generic]
145-
_subscriptions.delete(handler);
146147
},
147148

148149
/**

Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js

+32-36
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* @flow strict-local
99
*/
1010

11+
import type EventEmitter from '../../vendor/emitter/EventEmitter';
1112
import RCTDeviceEventEmitter from '../../EventEmitter/RCTDeviceEventEmitter';
1213
import NativeAccessibilityManager from './NativeAccessibilityManager';
1314
import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
@@ -16,15 +17,15 @@ import {sendAccessibilityEvent} from '../../Renderer/shims/ReactNative';
1617
import legacySendAccessibilityEvent from './legacySendAccessibilityEvent';
1718
import {type ElementRef} from 'react';
1819

19-
const CHANGE_EVENT_NAME = {
20-
announcementFinished: 'announcementFinished',
21-
boldTextChanged: 'boldTextChanged',
22-
grayscaleChanged: 'grayscaleChanged',
23-
invertColorsChanged: 'invertColorsChanged',
24-
reduceMotionChanged: 'reduceMotionChanged',
25-
reduceTransparencyChanged: 'reduceTransparencyChanged',
26-
screenReaderChanged: 'screenReaderChanged',
27-
};
20+
const SupportedEvents: Set<string> = new Set([
21+
'announcementFinished',
22+
'boldTextChanged',
23+
'grayscaleChanged',
24+
'invertColorsChanged',
25+
'reduceMotionChanged',
26+
'reduceTransparencyChanged',
27+
'screenReaderChanged',
28+
]);
2829

2930
type AccessibilityEventDefinitions = {
3031
boldTextChanged: [boolean],
@@ -46,8 +47,6 @@ type AccessibilityEventDefinitions = {
4647
// 'click' event type is not implemented in iOS. It's declared here to avoid flow type errors
4748
type AccessibilityEventTypes = 'focus' | 'click';
4849

49-
const _subscriptions = new Map();
50-
5150
/**
5251
* Sometimes it's useful to know whether or not the device has a screen reader
5352
* that is currently active. The `AccessibilityInfo` API is designed for this
@@ -217,24 +216,15 @@ const AccessibilityInfo = {
217216
eventName: K,
218217
handler: (...$ElementType<AccessibilityEventDefinitions, K>) => void,
219218
): EventSubscription {
220-
let subscription: EventSubscription;
221-
222219
if (eventName === 'change') {
223-
subscription = RCTDeviceEventEmitter.addListener(
224-
CHANGE_EVENT_NAME.screenReaderChanged,
225-
handler,
226-
);
227-
} else if (CHANGE_EVENT_NAME[eventName]) {
228-
subscription = RCTDeviceEventEmitter.addListener(eventName, handler);
220+
return RCTDeviceEventEmitter.addListener('screenReaderChanged', handler);
221+
}
222+
if (SupportedEvents.has(eventName)) {
223+
return RCTDeviceEventEmitter.addListener(eventName, handler);
229224
}
230-
231-
// $FlowFixMe[escaped-generic]
232-
_subscriptions.set(handler, subscription);
233-
234225
return {
235-
remove: () => {
236-
// $FlowIssue[incompatible-call] flow does not recognize handler properly
237-
AccessibilityInfo.removeEventListener<K>(eventName, handler);
226+
remove(): void {
227+
// Do nothing.
238228
},
239229
};
240230
},
@@ -271,22 +261,28 @@ const AccessibilityInfo = {
271261
},
272262

273263
/**
274-
* Remove an event handler.
275-
*
276-
* See https://reactnative.dev/docs/accessibilityinfo.html#removeeventlistener
264+
* @deprecated Use `remove` on the EventSubscription from `addEventListener`.
277265
*/
278266
removeEventListener: function<K: $Keys<AccessibilityEventDefinitions>>(
279267
eventName: K,
280268
handler: (...$ElementType<AccessibilityEventDefinitions, K>) => void,
281269
): void {
282-
// $FlowFixMe[escaped-generic]
283-
const listener = _subscriptions.get(handler);
284-
if (!listener) {
285-
return;
270+
// NOTE: This will report a deprecation notice via `console.error`.
271+
if (eventName === 'change') {
272+
// $FlowIgnore[incompatible-cast]
273+
(RCTDeviceEventEmitter: EventEmitter<$FlowFixMe>).removeListener(
274+
'screenReaderChanged',
275+
// $FlowFixMe[invalid-tuple-arity]
276+
handler,
277+
);
278+
} else if (SupportedEvents.has(eventName)) {
279+
// $FlowIgnore[incompatible-cast]
280+
(RCTDeviceEventEmitter: EventEmitter<$FlowFixMe>).removeListener(
281+
eventName,
282+
// $FlowFixMe[invalid-tuple-arity]
283+
handler,
284+
);
286285
}
287-
listener.remove();
288-
// $FlowFixMe[escaped-generic]
289-
_subscriptions.delete(handler);
290286
},
291287
};
292288

0 commit comments

Comments
 (0)