From ecb876f4d583a023c353dae4901d5a37e9f93fb5 Mon Sep 17 00:00:00 2001 From: Fabrizio Cucci Date: Mon, 13 Jan 2025 09:30:37 -0800 Subject: [PATCH 1/3] [skip ci] Migrate rn-tester/js/examples/OrientationChange/OrientationChangeExample.js to function components (#48643) Summary: As per title. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D68095232 --- .../OrientationChangeExample.js | 64 ++++++++----------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/packages/rn-tester/js/examples/OrientationChange/OrientationChangeExample.js b/packages/rn-tester/js/examples/OrientationChange/OrientationChangeExample.js index d7903ef3351e80..a6da8817b56a86 100644 --- a/packages/rn-tester/js/examples/OrientationChange/OrientationChangeExample.js +++ b/packages/rn-tester/js/examples/OrientationChange/OrientationChangeExample.js @@ -10,51 +10,41 @@ import RNTesterText from '../../components/RNTesterText'; import React from 'react'; +import {useEffect, useState} from 'react'; import {DeviceEventEmitter, View} from 'react-native'; -import {type EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter'; -class OrientationChangeExample extends React.Component<{...}, $FlowFixMeState> { - _orientationSubscription: EventSubscription; - - state: - | any - | { - currentOrientation: string, - isLandscape: boolean, - orientationDegrees: number, - } = { +const OrientationChangeExample = (): React.Node => { + const [state, setState] = useState({ currentOrientation: '', orientationDegrees: 0, isLandscape: false, - }; - - componentDidMount() { - this._orientationSubscription = DeviceEventEmitter.addListener( + }); + + useEffect(() => { + const onOrientationChange = (orientation: Object) => { + setState({ + currentOrientation: orientation.name, + orientationDegrees: orientation.rotationDegrees, + isLandscape: orientation.isLandscape, + }); + }; + + const orientationSubscription = DeviceEventEmitter.addListener( 'namedOrientationDidChange', - this._onOrientationChange, + onOrientationChange, ); - } - - componentWillUnmount() { - this._orientationSubscription.remove(); - } - _onOrientationChange = (orientation: Object) => { - this.setState({ - currentOrientation: orientation.name, - orientationDegrees: orientation.rotationDegrees, - isLandscape: orientation.isLandscape, - }); - }; - - render(): React.Node { - return ( - - {JSON.stringify(this.state)} - - ); - } -} + return () => { + orientationSubscription.remove(); + }; + }, []); + + return ( + + {JSON.stringify(state)} + + ); +}; exports.title = 'OrientationChangeExample'; exports.category = 'Basic'; From f1ea92bdef15523c735753448736d7b21bb7b257 Mon Sep 17 00:00:00 2001 From: Fabrizio Cucci Date: Mon, 13 Jan 2025 09:30:37 -0800 Subject: [PATCH 2/3] [skip ci] Migrate rn-tester/js/examples/AppState/AppStateExample.js to function components (#48644) Summary: As per title. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D68095480 --- .../js/examples/AppState/AppStateExample.js | 135 ++++++++---------- 1 file changed, 58 insertions(+), 77 deletions(-) diff --git a/packages/rn-tester/js/examples/AppState/AppStateExample.js b/packages/rn-tester/js/examples/AppState/AppStateExample.js index f4e132ba2d4b84..2415cb0c418ccf 100644 --- a/packages/rn-tester/js/examples/AppState/AppStateExample.js +++ b/packages/rn-tester/js/examples/AppState/AppStateExample.js @@ -11,109 +11,90 @@ 'use strict'; import type {RNTesterModuleExample} from '../../types/RNTesterTypes'; -import type {AppStateValues} from 'react-native/Libraries/AppState/AppState'; -import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter'; import RNTesterText from '../../components/RNTesterText'; import React from 'react'; +import {useEffect, useState} from 'react'; import {AppState, Platform, View} from 'react-native'; -class AppStateSubscription extends React.Component< - $FlowFixMeProps, - $FlowFixMeState, -> { - state: { - appState: ?string, - eventsDetected: Array, - memoryWarnings: number, - previousAppStates: Array, - } = { - appState: AppState.currentState, - previousAppStates: [], - memoryWarnings: 0, - eventsDetected: [], - }; +type Props = { + detectEvents?: boolean, + showCurrentOnly?: boolean, + showMemoryWarnings?: boolean, +}; - _subscriptions: ?Array; +function AppStateSubscription(props: Props) { + const [currentAppState, setCurrentAppState] = useState( + AppState.currentState, + ); + const [previousAppStates, setPreviousAppStates] = useState([]); + const [memoryWarnings, setMemoryWarnings] = useState(0); + const [eventsDetected, setEventsDetected] = useState([]); - componentDidMount() { - this._subscriptions = [ - AppState.addEventListener('change', this._handleAppStateChange), - AppState.addEventListener('memoryWarning', this._handleMemoryWarning), + useEffect(() => { + const subscriptions = [ + AppState.addEventListener('change', handleAppStateChange), + AppState.addEventListener('memoryWarning', handleMemoryWarning), ]; + if (Platform.OS === 'android') { - this._subscriptions.push( - AppState.addEventListener('focus', this._handleFocus), - AppState.addEventListener('blur', this._handleBlur), + subscriptions.push( + AppState.addEventListener('focus', handleFocus), + AppState.addEventListener('blur', handleBlur), ); } - } - componentWillUnmount() { - if (this._subscriptions != null) { - for (const subscription of this._subscriptions) { - subscription.remove(); - } - } - } + return () => { + subscriptions.forEach(subscription => subscription.remove()); + }; + }, []); - _handleMemoryWarning = () => { - this.setState({memoryWarnings: this.state.memoryWarnings + 1}); + const handleMemoryWarning = () => { + setMemoryWarnings(prev => prev + 1); }; - _handleBlur = () => { - const eventsDetected = this.state.eventsDetected.slice(); - eventsDetected.push('blur'); - this.setState({eventsDetected}); + const handleBlur = () => { + setEventsDetected(prev => [...prev, 'blur']); }; - _handleFocus = () => { - const eventsDetected = this.state.eventsDetected.slice(); - eventsDetected.push('focus'); - this.setState({eventsDetected}); + const handleFocus = () => { + setEventsDetected(prev => [...prev, 'focus']); }; - _handleAppStateChange = (appState: AppStateValues) => { - const previousAppStates = this.state.previousAppStates.slice(); - previousAppStates.push(this.state.appState); - this.setState({ - appState, - previousAppStates, - }); + const handleAppStateChange = (appState: string) => { + setPreviousAppStates(prev => [...prev, appState]); + setCurrentAppState(appState); }; - render(): React.Node { - if (this.props.showMemoryWarnings) { - return ( - - {this.state.memoryWarnings} - - ); - } - if (this.props.showCurrentOnly) { - return ( - - {this.state.appState} - - ); - } - if (this.props.detectEvents) { - return ( - - - {JSON.stringify(this.state.eventsDetected)} - - - ); - } + if (props.showMemoryWarnings) { + return ( + + {memoryWarnings} + + ); + } + + if (props.showCurrentOnly) { + return ( + + {currentAppState} + + ); + } + + if (props.detectEvents) { return ( - - {JSON.stringify(this.state.previousAppStates)} - + {JSON.stringify(eventsDetected)} ); } + + return ( + + {JSON.stringify(previousAppStates)} + + ); } exports.title = 'AppState'; From ef07ee789d3e8c9df02a4febb442d732500f9519 Mon Sep 17 00:00:00 2001 From: Fabrizio Cucci Date: Mon, 13 Jan 2025 09:30:37 -0800 Subject: [PATCH 3/3] Migrate rn-tester/js/components/RNTesterButton.js to function components (#48645) Summary: As per title. Changelog: [Internal] Reviewed By: cortinico Differential Revision: D68098118 --- .../rn-tester/js/components/RNTesterButton.js | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/rn-tester/js/components/RNTesterButton.js b/packages/rn-tester/js/components/RNTesterButton.js index d760b3a00ea230..686301af61567b 100644 --- a/packages/rn-tester/js/components/RNTesterButton.js +++ b/packages/rn-tester/js/components/RNTesterButton.js @@ -12,8 +12,8 @@ import type {PressEvent} from 'react-native/Libraries/Types/CoreEventTypes'; -const React = require('react'); -const {Pressable, StyleSheet, Text} = require('react-native'); +import React from 'react'; +import {Pressable, StyleSheet, Text} from 'react-native'; type Props = $ReadOnly<{| testID?: string, @@ -22,17 +22,15 @@ type Props = $ReadOnly<{| onPress?: ?(event: PressEvent) => mixed, |}>; -class RNTesterButton extends React.Component { - render(): React.Node { - return ( - [styles.button, pressed && styles.pressed]}> - {this.props.children} - - ); - } +function RNTesterButton(props: Props): React.Node { + return ( + [styles.button, pressed && styles.pressed]}> + {props.children} + + ); } const styles = StyleSheet.create({ @@ -51,4 +49,4 @@ const styles = StyleSheet.create({ }, }); -module.exports = RNTesterButton; +export default RNTesterButton;