From 305b4253c2a9ed4d71be33e02cb12b6d570e2fb1 Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Wed, 3 Mar 2021 21:41:12 -0800 Subject: [PATCH] RN: Change Appearance to Return EventSubscription Summary: Changes `Appearance.addChangeListener` to return an `EventSubscription` object that has a `remove()` method on it. In an upcoming commit, calling `Appearance.removeChangeListener` will lead to a deprecation warning. Changelog: [General][Change] - `Appearance.addChangeListener` now returns an `EventSubscription`. Reviewed By: kacieb Differential Revision: D26696388 fbshipit-source-id: d0bdeffff3a2a366b3c11b6dc1417dfb2f1455c2 --- Libraries/Utilities/Appearance.js | 13 +++++++++---- Libraries/Utilities/useColorScheme.js | 6 ++++-- .../js/examples/Appearance/AppearanceExample.js | 17 ++++++++++------- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Libraries/Utilities/Appearance.js b/Libraries/Utilities/Appearance.js index e6a4f9b7849713..1d633fef098c3c 100644 --- a/Libraries/Utilities/Appearance.js +++ b/Libraries/Utilities/Appearance.js @@ -8,7 +8,9 @@ * @flow strict-local */ -import EventEmitter from '../vendor/emitter/EventEmitter'; +import EventEmitter, { + type EventSubscription, +} from '../vendor/emitter/EventEmitter'; import NativeEventEmitter from '../EventEmitter/NativeEventEmitter'; import NativeAppearance, { type AppearancePreferences, @@ -78,16 +80,19 @@ module.exports = { ); return nativeColorScheme; }, + /** * Add an event handler that is fired when appearance preferences change. */ - addChangeListener(listener: AppearanceListener): void { - eventEmitter.addListener('change', listener); + addChangeListener(listener: AppearanceListener): EventSubscription { + return eventEmitter.addListener('change', listener); }, + /** - * Remove an event handler. + * @deprecated Use `remove` on the EventSubscription from `addEventListener`. */ removeChangeListener(listener: AppearanceListener): void { + // NOTE: This will report a deprecation notice via `console.error`. eventEmitter.removeListener('change', listener); }, }; diff --git a/Libraries/Utilities/useColorScheme.js b/Libraries/Utilities/useColorScheme.js index 2712a846e586a7..2c7ffa5d29bb35 100644 --- a/Libraries/Utilities/useColorScheme.js +++ b/Libraries/Utilities/useColorScheme.js @@ -18,8 +18,10 @@ export default function useColorScheme(): ?ColorSchemeName { () => ({ getCurrentValue: () => Appearance.getColorScheme(), subscribe: callback => { - Appearance.addChangeListener(callback); - return () => Appearance.removeChangeListener(callback); + const appearanceSubscription = Appearance.addChangeListener(callback); + return () => { + appearanceSubscription.remove(); + }; }, }), [], diff --git a/packages/rn-tester/js/examples/Appearance/AppearanceExample.js b/packages/rn-tester/js/examples/Appearance/AppearanceExample.js index c7cc76fec7ea81..55b38f03346f2c 100644 --- a/packages/rn-tester/js/examples/Appearance/AppearanceExample.js +++ b/packages/rn-tester/js/examples/Appearance/AppearanceExample.js @@ -11,29 +11,32 @@ import * as React from 'react'; import {Appearance, Text, useColorScheme, View} from 'react-native'; import type {AppearancePreferences} from 'react-native/Libraries/Utilities/NativeAppearance'; +import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter'; import {RNTesterThemeContext, themes} from '../../components/RNTesterTheme'; class ColorSchemeSubscription extends React.Component< {...}, {colorScheme: ?string, ...}, > { + _subscription: ?EventSubscription; + state = { colorScheme: Appearance.getColorScheme(), }; componentDidMount() { - Appearance.addChangeListener(this._handleAppearanceChange); + this._subscription = Appearance.addChangeListener( + (preferences: AppearancePreferences) => { + const {colorScheme} = preferences; + this.setState({colorScheme}); + }, + ); } componentWillUnmount() { - Appearance.removeChangeListener(this._handleAppearanceChange); + this._subscription?.remove(); } - _handleAppearanceChange = (preferences: AppearancePreferences) => { - const {colorScheme} = preferences; - this.setState({colorScheme}); - }; - render() { return (