diff --git a/packages/rn-tester/js/components/TextInlineView.js b/packages/rn-tester/js/components/TextInlineView.js index 360a15a17cb1..c7e884ae2250 100644 --- a/packages/rn-tester/js/components/TextInlineView.js +++ b/packages/rn-tester/js/components/TextInlineView.js @@ -12,6 +12,7 @@ import RNTesterText from '../components/RNTesterText'; import React from 'react'; +import {useState} from 'react'; import {Image, TouchableHighlight, View} from 'react-native'; function Basic(): React.Node { @@ -105,116 +106,97 @@ function ClippedByText(): React.Node { ); } -type ChangeSizeState = {| - width: number, -|}; - -class ChangeImageSize extends React.Component { - state: ChangeSizeState = { - width: 50, - }; - - render(): React.Node { - return ( - - { - this.setState({width: this.state.width === 50 ? 100 : 50}); - }}> - - Change Image Width (width={this.state.width}) - - - - This is an - - inline image +function ChangeImageSize(): React.Node { + const [width, setWidth] = useState(50); + return ( + + { + setWidth(width === 50 ? 100 : 50); + }}> + + Change Image Width (width={width}) - - ); - } + + + This is an + + inline image + + + ); } -class ChangeViewSize extends React.Component { - state: ChangeSizeState = { - width: 50, - }; +function ChangeViewSize(): React.Node { + const [width, setWidth] = useState(50); + return ( + + { + setWidth(width === 50 ? 100 : 50); + }}> + + Change View Width (width={width}) + + + + This is an + + inline view + + + ); +} - render(): React.Node { - return ( - - { - this.setState({width: this.state.width === 50 ? 100 : 50}); - }}> - - Change View Width (width={this.state.width}) - - - - This is an +function ChangeInnerViewSize(): React.Node { + const [width, setWidth] = useState(50); + return ( + + { + setWidth(width === 50 ? 100 : 50); + }}> + {/* When updating `width`, it's important that the only thing that + changes is the width of the pink inline view. When we do this, we + demonstrate a bug in RN Android where the pink view doesn't get + rerendered and remains at its old size. If other things change + (e.g. we display `width` as text somewhere) it could circumvent + the bug and cause the pink view to be rerendered at its new size. */} + + Change Pink View Width + + + + This is an + - inline view - - - ); - } -} - -class ChangeInnerViewSize extends React.Component { - state: ChangeSizeState = { - width: 50, - }; - - render(): React.Node { - return ( - - { - this.setState({width: this.state.width === 50 ? 100 : 50}); - }}> - {/* When updating `state.width`, it's important that the only thing that - changes is the width of the pink inline view. When we do this, we - demonstrate a bug in RN Android where the pink view doesn't get - rerendered and remains at its old size. If other things change - (e.g. we display `state.width` as text somewhere) it could circumvent - the bug and cause the pink view to be rerendered at its new size. */} - - Change Pink View Width - - - - This is an - - - - inline view - - - ); - } + + inline view + + + ); } module.exports = { diff --git a/packages/rn-tester/js/examples/AppState/AppStateExample.js b/packages/rn-tester/js/examples/AppState/AppStateExample.js index f4e132ba2d4b..2415cb0c418c 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'; diff --git a/packages/rn-tester/js/examples/OrientationChange/OrientationChangeExample.js b/packages/rn-tester/js/examples/OrientationChange/OrientationChangeExample.js index d7903ef3351e..a6da8817b56a 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';