mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-28 08:34:31 +00:00
[fix] AppState addEventListener returns subscription object
Close #2129
This commit is contained in:
committed by
Nicolas Gallagher
parent
4aba2bdcf4
commit
126642783b
@@ -36,7 +36,7 @@ Returns the current state of the app.
|
||||
|
||||
### Static methods
|
||||
|
||||
{% call macro.prop('addEventListener', '(type: ?string, listener: (boolean) => void) => void') %}
|
||||
{% call macro.prop('addEventListener', '(type: ?string, listener: (boolean) => void) => ?EmitterSubscription') %}
|
||||
Add a listener to `AppState` changes. Listen to the `"change"` event type. The handler is called with the app state value.
|
||||
{% endcall %}
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ export default function AppStatePage() {
|
||||
}));
|
||||
};
|
||||
|
||||
AppState.addEventListener('change', handleChange);
|
||||
const subscription = AppState.addEventListener('change', handleChange);
|
||||
return () => {
|
||||
AppState.removeEventListener('change', handleChange);
|
||||
subscription.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -5,22 +5,22 @@ import AppState from '..';
|
||||
describe('apis/AppState', () => {
|
||||
const handler = () => {};
|
||||
|
||||
afterEach(() => {
|
||||
try {
|
||||
AppState.removeEventListener('change', handler);
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
describe('addEventListener', () => {
|
||||
test('throws if the provided "eventType" is not supported', () => {
|
||||
expect(() => AppState.addEventListener('foo', handler)).toThrow();
|
||||
expect(() => AppState.addEventListener('change', handler)).not.toThrow();
|
||||
expect(() => AppState.addEventListener('change', handler).remove()).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeEventListener', () => {
|
||||
test('throws if the handler is not registered', () => {
|
||||
expect(() => AppState.removeEventListener('change', handler)).toThrow();
|
||||
beforeEach(() => {
|
||||
// removeEventListener logs a deprecation warning, ignore
|
||||
jest.spyOn(console, 'error');
|
||||
console.error.mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
console.error.mockRestore();
|
||||
});
|
||||
|
||||
test('throws if the provided "eventType" is not supported', () => {
|
||||
|
||||
+17
-14
@@ -9,8 +9,8 @@
|
||||
*/
|
||||
|
||||
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
|
||||
import findIndex from 'array-find-index';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import EventEmitter from '../../vendor/react-native/emitter/_EventEmitter';
|
||||
|
||||
// Android 4.4 browser
|
||||
const isPrefixed =
|
||||
@@ -25,7 +25,7 @@ const AppStates = {
|
||||
ACTIVE: 'active'
|
||||
};
|
||||
|
||||
const listeners = [];
|
||||
let changeEmitter = null;
|
||||
|
||||
export default class AppState {
|
||||
static isAvailable = canUseDOM && document[VISIBILITY_STATE_PROPERTY];
|
||||
@@ -53,9 +53,19 @@ export default class AppState {
|
||||
type
|
||||
);
|
||||
if (type === 'change') {
|
||||
const callback = () => handler(AppState.currentState);
|
||||
listeners.push([handler, callback]);
|
||||
document.addEventListener(VISIBILITY_CHANGE_EVENT, callback, false);
|
||||
if (!changeEmitter) {
|
||||
changeEmitter = new EventEmitter();
|
||||
document.addEventListener(
|
||||
VISIBILITY_CHANGE_EVENT,
|
||||
() => {
|
||||
if (changeEmitter) {
|
||||
changeEmitter.emit('change', AppState.currentState);
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
}
|
||||
return changeEmitter.addListener(type, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,15 +77,8 @@ export default class AppState {
|
||||
'Trying to remove listener for unknown event: "%s"',
|
||||
type
|
||||
);
|
||||
if (type === 'change') {
|
||||
const listenerIndex = findIndex(listeners, (pair) => pair[0] === handler);
|
||||
invariant(
|
||||
listenerIndex !== -1,
|
||||
'Trying to remove AppState listener for unregistered handler'
|
||||
);
|
||||
const callback = listeners[listenerIndex][1];
|
||||
document.removeEventListener(VISIBILITY_CHANGE_EVENT, callback, false);
|
||||
listeners.splice(listenerIndex, 1);
|
||||
if (type === 'change' && changeEmitter) {
|
||||
changeEmitter.removeListener(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user