diff --git a/native/components/search.react.js b/native/components/search.react.js index ee290ef85..96c198a9a 100644 --- a/native/components/search.react.js +++ b/native/components/search.react.js @@ -1,135 +1,89 @@ // @flow -import PropTypes from 'prop-types'; import * as React from 'react'; -import { View, ViewPropTypes, TouchableOpacity, TextInput } from 'react-native'; +import { View, TouchableOpacity, TextInput } from 'react-native'; import Icon from 'react-native-vector-icons/FontAwesome'; import { isLoggedIn } from 'lib/selectors/user-selectors'; -import { connect } from 'lib/utils/redux-utils'; -import type { AppState } from '../redux/redux-setup'; -import { - type Colors, - colorsPropType, - colorsSelector, - styleSelector, -} from '../themes/colors'; +import { useSelector } from '../redux/redux-utils'; +import { useStyles, useColors } from '../themes/colors'; import type { ViewStyle } from '../types/styles'; type Props = {| ...React.ElementConfig, - searchText: string, - onChangeText: (searchText: string) => mixed, - containerStyle?: ViewStyle, - textInputRef?: React.Ref, - // Redux state - colors: Colors, - styles: typeof styles, - loggedIn: boolean, + +searchText: string, + +onChangeText: (searchText: string) => mixed, + +containerStyle?: ViewStyle, |}; -class Search extends React.PureComponent { - static propTypes = { - searchText: PropTypes.string.isRequired, - onChangeText: PropTypes.func.isRequired, - containerStyle: ViewPropTypes.style, - textInputRef: PropTypes.func, - colors: colorsPropType.isRequired, - styles: PropTypes.objectOf(PropTypes.object).isRequired, - loggedIn: PropTypes.bool.isRequired, - }; +const Search = React.forwardRef( + function ForwardedSearch(props: Props, ref: React.Ref) { + const { onChangeText, searchText, containerStyle, ...rest } = props; - componentDidUpdate(prevProps: Props) { - if (!this.props.loggedIn && prevProps.loggedIn) { - this.clearSearch(); - } - } + const clearSearch = React.useCallback(() => { + onChangeText(''); + }, [onChangeText]); + + const loggedIn = useSelector(isLoggedIn); + const styles = useStyles(unboundStyles); + const colors = useColors(); + const prevLoggedInRef = React.useRef(); + React.useEffect(() => { + const prevLoggedIn = prevLoggedInRef.current; + prevLoggedInRef.current = loggedIn; + if (!loggedIn && prevLoggedIn) { + clearSearch(); + } + }, [loggedIn, clearSearch]); - render() { - const { - searchText, - onChangeText, - containerStyle, - textInputRef, - colors, - styles, - loggedIn, - ...rest - } = this.props; const { listSearchIcon: iconColor } = colors; let clearSearchInputIcon = null; if (searchText) { clearSearchInputIcon = ( - + ); } const textInputProps: React.ElementProps = { style: styles.searchInput, value: searchText, onChangeText: onChangeText, placeholderTextColor: iconColor, returnKeyType: 'go', }; return ( - + - + {clearSearchInputIcon} ); - } - - clearSearch = () => { - this.props.onChangeText(''); - }; -} + }, +); -const styles = { +const unboundStyles = { search: { alignItems: 'center', backgroundColor: 'listSearchBackground', borderRadius: 6, flexDirection: 'row', paddingLeft: 14, paddingRight: 12, paddingVertical: 6, }, searchInput: { color: 'listForegroundLabel', flex: 1, fontSize: 16, marginLeft: 8, marginVertical: 0, padding: 0, borderBottomColor: 'transparent', }, }; -const stylesSelector = styleSelector(styles); - -const ConnectedSearch = connect((state: AppState) => ({ - colors: colorsSelector(state), - styles: stylesSelector(state), - loggedIn: isLoggedIn(state), -}))(Search); -type ConnectedProps = $Diff< - Props, - {| - colors: Colors, - styles: typeof styles, - loggedIn: boolean, - |}, ->; -export default React.forwardRef( - function ForwardedConnectedSearch( - props: ConnectedProps, - ref: React.Ref, - ) { - return ; - }, -); +export default React.memo(Search);