From 2cce1148f9446f87e51f7d635e329b4fd2e9ebf3 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 12:51:41 -0600
Subject: [PATCH 01/18] track view height

---
 src/components/AddressSearch.js | 110 +++++++++++++++++---------------
 1 file changed, 60 insertions(+), 50 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index a83534eb05c2..cd7f9aeb7fab 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -1,7 +1,7 @@
 import _ from 'underscore';
-import React, {useEffect, useRef} from 'react';
+import React, {useEffect, useState, useRef} from 'react';
 import PropTypes from 'prop-types';
-import {LogBox} from 'react-native';
+import {LogBox, View} from 'react-native';
 import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
 import CONFIG from '../CONFIG';
 import withLocalize, {withLocalizePropTypes} from './withLocalize';
@@ -37,6 +37,7 @@ const defaultProps = {
 
 const AddressSearch = (props) => {
     const googlePlacesRef = useRef();
+    const [display, setDisplay] = useState(false);
     useEffect(() => {
         if (!googlePlacesRef.current) {
             return;
@@ -79,55 +80,64 @@ const AddressSearch = (props) => {
     };
 
     return (
-        <GooglePlacesAutocomplete
-            ref={googlePlacesRef}
-            fetchDetails
-            suppressDefaultStyles
-            enablePoweredByContainer={false}
-            onPress={(data, details) => saveLocationDetails(details)}
-            query={{
-                key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
-                language: props.preferredLocale,
-                types: 'address',
-                components: 'country:us',
+        <View 
+            // We use the View height to determine if we should hide the border and margin of the listView dropdown
+            // to prevent a lingering border when there are no address suggestions
+            onLayout={(event) => {
+                const {height} = event.nativeEvent.layout;
+                height > 74 ? setDisplay(true) : setDisplay(false);s
             }}
-            requestUrl={{
-                useOnPlatform: 'web',
-                url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
-            }}
-            textInputProps={{
-                InputComp: ExpensiTextInput,
-                label: props.label,
-                containerStyles: props.containerStyles,
-                errorText: props.errorText,
-                onChangeText: (text) => {
-                    const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value);
-
-                    // Ensure whether an address is selected already or has address value initialized.
-                    if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) {
-                        saveLocationDetails({});
-                    }
-                },
-            }}
-            styles={{
-                textInputContainer: [styles.flexColumn],
-                listView: [
-                    styles.borderTopRounded,
-                    styles.borderBottomRounded,
-                    styles.mt1,
-                    styles.overflowAuto,
-                    styles.borderLeft,
-                    styles.borderRight,
-                ],
-                row: [
-                    styles.pv4,
-                    styles.ph3,
-                    styles.overflowAuto,
-                ],
-                description: [styles.googleSearchText],
-                separator: [styles.googleSearchSeparator],
-            }}
-        />
+        >
+            <GooglePlacesAutocomplete
+                ref={googlePlacesRef}
+                fetchDetails
+                suppressDefaultStyles
+                enablePoweredByContainer={false}
+                onPress={(data, details) => saveLocationDetails(details)}
+                query={{
+                    key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
+                    language: props.preferredLocale,
+                    types: 'address',
+                    components: 'country:us',
+                }}
+                requestUrl={{
+                    useOnPlatform: 'web',
+                    url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
+                }}
+                textInputProps={{
+                    InputComp: ExpensiTextInput,
+                    label: props.label,
+                    containerStyles: props.containerStyles,
+                    errorText: props.errorText,
+                    onChangeText: (text) => {
+                        const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value);
+    
+                        // Ensure whether an address is selected already or has address value initialized.
+                        if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) {
+                            saveLocationDetails({});
+                        }
+                    },
+                }}
+                styles={{
+                    textInputContainer: [styles.flexColumn],
+                    listView: [
+                        display && styles.borderTopRounded,
+                        display && styles.borderBottomRounded,
+                        display && styles.mt1,
+                        styles.overflowAuto,
+                        styles.borderLeft,
+                        styles.borderRight,
+                    ],
+                    row: [
+                        styles.pv4,
+                        styles.ph3,
+                        styles.overflowAuto,
+                    ],
+                    description: [styles.googleSearchText],
+                    separator: [styles.googleSearchSeparator],
+                }}
+            />
+        </View>
     );
 };
 

From ac9ba8fee4a0679bcf18d2da0fc56e4ea0105dd3 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 12:52:45 -0600
Subject: [PATCH 02/18] remove char

---
 src/components/AddressSearch.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index cd7f9aeb7fab..6f3871d1bc33 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -85,7 +85,7 @@ const AddressSearch = (props) => {
             // to prevent a lingering border when there are no address suggestions
             onLayout={(event) => {
                 const {height} = event.nativeEvent.layout;
-                height > 74 ? setDisplay(true) : setDisplay(false);s
+                height > 74 ? setDisplay(true) : setDisplay(false);
             }}
         >
             <GooglePlacesAutocomplete

From 2cd29d947d469e23978bdda315ab416def06969d Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 13:41:14 -0600
Subject: [PATCH 03/18] fix style

---
 src/components/AddressSearch.js | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 6f3871d1bc33..48bf4adfb021 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -80,12 +80,13 @@ const AddressSearch = (props) => {
     };
 
     return (
-        <View 
-            // We use the View height to determine if we should hide the border and margin of the listView dropdown
-            // to prevent a lingering border when there are no address suggestions
+
+        // We use the View height to determine if we should hide the border and margin of the listView dropdown
+        // to prevent a lingering border when there are no address suggestions
+        <View
             onLayout={(event) => {
                 const {height} = event.nativeEvent.layout;
-                height > 74 ? setDisplay(true) : setDisplay(false);
+                return height > 74 ? setDisplay(true) : setDisplay(false);
             }}
         >
             <GooglePlacesAutocomplete
@@ -111,7 +112,7 @@ const AddressSearch = (props) => {
                     errorText: props.errorText,
                     onChangeText: (text) => {
                         const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value);
-    
+
                         // Ensure whether an address is selected already or has address value initialized.
                         if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) {
                             saveLocationDetails({});

From d8e24c7817e828eaf976fa4ab3f44022a53aaad3 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 14:35:53 -0600
Subject: [PATCH 04/18] convert to class component

---
 src/components/AddressSearch.js | 163 +++++++++++++++++---------------
 1 file changed, 86 insertions(+), 77 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 48bf4adfb021..816b4540f510 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -1,5 +1,5 @@
 import _ from 'underscore';
-import React, {useEffect, useState, useRef} from 'react';
+import React from 'react';
 import PropTypes from 'prop-types';
 import {LogBox, View} from 'react-native';
 import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
@@ -35,18 +35,25 @@ const defaultProps = {
     containerStyles: null,
 };
 
-const AddressSearch = (props) => {
-    const googlePlacesRef = useRef();
-    const [display, setDisplay] = useState(false);
-    useEffect(() => {
-        if (!googlePlacesRef.current) {
+class AddressSearch extends React.Component {
+    constructor(props) {
+        super(props);
+
+        this.state = {
+            displayDropdownBorder: false,
+        }
+        this.googlePlacesRef = React.createRef();
+    }
+
+    componentDidMount() {
+        if (!this.googlePlacesRef.current) {
             return;
         }
 
-        googlePlacesRef.current.setAddressText(props.value);
-    }, []);
+        this.googlePlacesRef.current.setAddressText(this.props.value);
+    }
 
-    const saveLocationDetails = (details) => {
+    saveLocationDetails(details) {
         const addressComponents = details.address_components;
         if (isAddressValidForVBA(addressComponents)) {
             // Gather the values from the Google details
@@ -61,10 +68,10 @@ const AddressSearch = (props) => {
             const zipCode = getAddressComponent(addressComponents, 'postal_code', 'long_name');
 
             // Trigger text change events for each of the individual fields being saved on the server
-            props.onChangeText('addressStreet', `${streetNumber} ${streetName}`);
-            props.onChangeText('addressCity', city);
-            props.onChangeText('addressState', state);
-            props.onChangeText('addressZipCode', zipCode);
+            this.props.onChangeText('addressStreet', `${streetNumber} ${streetName}`);
+            this.props.onChangeText('addressCity', city);
+            this.props.onChangeText('addressState', state);
+            this.props.onChangeText('addressZipCode', zipCode);
         } else {
             // Clear the values associated to the address, so our validations catch the problem
             Log.hmmm('[AddressSearch] Search result failed validation: ', {
@@ -72,74 +79,76 @@ const AddressSearch = (props) => {
                 address_components: addressComponents,
                 place_id: details.place_id,
             });
-            props.onChangeText('addressStreet', null);
-            props.onChangeText('addressCity', null);
-            props.onChangeText('addressState', null);
-            props.onChangeText('addressZipCode', null);
+            this.props.onChangeText('addressStreet', null);
+            this.props.onChangeText('addressCity', null);
+            this.props.onChangeText('addressState', null);
+            this.props.onChangeText('addressZipCode', null);
         }
     };
 
-    return (
-
-        // We use the View height to determine if we should hide the border and margin of the listView dropdown
-        // to prevent a lingering border when there are no address suggestions
-        <View
-            onLayout={(event) => {
-                const {height} = event.nativeEvent.layout;
-                return height > 74 ? setDisplay(true) : setDisplay(false);
-            }}
-        >
-            <GooglePlacesAutocomplete
-                ref={googlePlacesRef}
-                fetchDetails
-                suppressDefaultStyles
-                enablePoweredByContainer={false}
-                onPress={(data, details) => saveLocationDetails(details)}
-                query={{
-                    key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
-                    language: props.preferredLocale,
-                    types: 'address',
-                    components: 'country:us',
-                }}
-                requestUrl={{
-                    useOnPlatform: 'web',
-                    url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
-                }}
-                textInputProps={{
-                    InputComp: ExpensiTextInput,
-                    label: props.label,
-                    containerStyles: props.containerStyles,
-                    errorText: props.errorText,
-                    onChangeText: (text) => {
-                        const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value);
-
-                        // Ensure whether an address is selected already or has address value initialized.
-                        if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) {
-                            saveLocationDetails({});
-                        }
-                    },
-                }}
-                styles={{
-                    textInputContainer: [styles.flexColumn],
-                    listView: [
-                        display && styles.borderTopRounded,
-                        display && styles.borderBottomRounded,
-                        display && styles.mt1,
-                        styles.overflowAuto,
-                        styles.borderLeft,
-                        styles.borderRight,
-                    ],
-                    row: [
-                        styles.pv4,
-                        styles.ph3,
-                        styles.overflowAuto,
-                    ],
-                    description: [styles.googleSearchText],
-                    separator: [styles.googleSearchSeparator],
+    render() {
+        return (
+    
+            // We use the View height to determine if we should hide the border and margin of the listView dropdown
+            // to prevent a lingering border when there are no address suggestions
+            <View
+                onLayout={(event) => {
+                    const {height} = event.nativeEvent.layout;
+                    return height > 74 ? this.setState({displayDropdownBorder: true}) : this.setState({displayDropdownBorder: false});
                 }}
-            />
-        </View>
-    );
+            >
+                <GooglePlacesAutocomplete
+                    ref={this.googlePlacesRef}
+                    fetchDetails
+                    suppressDefaultStyles
+                    enablePoweredByContainer={false}
+                    onPress={(data, details) => this.saveLocationDetails(details)}
+                    query={{
+                        key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
+                        language: this.props.preferredLocale,
+                        types: 'address',
+                        components: 'country:us',
+                    }}
+                    requestUrl={{
+                        useOnPlatform: 'web',
+                        url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
+                    }}
+                    textInputProps={{
+                        InputComp: ExpensiTextInput,
+                        label: this.props.label,
+                        containerStyles: this.props.containerStyles,
+                        errorText: this.props.errorText,
+                        onChangeText: (text) => {
+                            const isTextValid = !_.isEmpty(text) && _.isEqual(text, this.props.value);
+    
+                            // Ensure whether an address is selected already or has address value initialized.
+                            if (!_.isEmpty(this.googlePlacesRef.current.getAddressText()) && !isTextValid) {
+                                this.saveLocationDetails({});
+                            }
+                        },
+                    }}
+                    styles={{
+                        textInputContainer: [styles.flexColumn],
+                        listView: [
+                            this.state.displayDropdownBorder && styles.borderTopRounded,
+                            this.state.displayDropdownBorder && styles.borderBottomRounded,
+                            this.state.displayDropdownBorder && styles.mt1,
+                            styles.overflowAuto,
+                            styles.borderLeft,
+                            styles.borderRight,
+                        ],
+                        row: [
+                            styles.pv4,
+                            styles.ph3,
+                            styles.overflowAuto,
+                        ],
+                        description: [styles.googleSearchText],
+                        separator: [styles.googleSearchSeparator],
+                    }}
+                />
+            </View>
+        );
+    }
 };
 
 AddressSearch.propTypes = propTypes;

From 7cf6954292721e90055c903a8556b40e9487c696 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 14:37:22 -0600
Subject: [PATCH 05/18] fix style

---
 src/components/AddressSearch.js | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 816b4540f510..c1fdd134af06 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -41,7 +41,7 @@ class AddressSearch extends React.Component {
 
         this.state = {
             displayDropdownBorder: false,
-        }
+        };
         this.googlePlacesRef = React.createRef();
     }
 
@@ -84,11 +84,11 @@ class AddressSearch extends React.Component {
             this.props.onChangeText('addressState', null);
             this.props.onChangeText('addressZipCode', null);
         }
-    };
+    }
 
     render() {
         return (
-    
+
             // We use the View height to determine if we should hide the border and margin of the listView dropdown
             // to prevent a lingering border when there are no address suggestions
             <View
@@ -120,7 +120,7 @@ class AddressSearch extends React.Component {
                         errorText: this.props.errorText,
                         onChangeText: (text) => {
                             const isTextValid = !_.isEmpty(text) && _.isEqual(text, this.props.value);
-    
+
                             // Ensure whether an address is selected already or has address value initialized.
                             if (!_.isEmpty(this.googlePlacesRef.current.getAddressText()) && !isTextValid) {
                                 this.saveLocationDetails({});
@@ -149,7 +149,7 @@ class AddressSearch extends React.Component {
             </View>
         );
     }
-};
+}
 
 AddressSearch.propTypes = propTypes;
 AddressSearch.defaultProps = defaultProps;

From 3355b5ee69037e2c25509c4543c0b8e0a278fc28 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 14:38:52 -0600
Subject: [PATCH 06/18] rename state variable

---
 src/components/AddressSearch.js | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index c1fdd134af06..5f8329fafe37 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -40,7 +40,7 @@ class AddressSearch extends React.Component {
         super(props);
 
         this.state = {
-            displayDropdownBorder: false,
+            displayListViewBorder: false,
         };
         this.googlePlacesRef = React.createRef();
     }
@@ -94,7 +94,7 @@ class AddressSearch extends React.Component {
             <View
                 onLayout={(event) => {
                     const {height} = event.nativeEvent.layout;
-                    return height > 74 ? this.setState({displayDropdownBorder: true}) : this.setState({displayDropdownBorder: false});
+                    return height > 74 ? this.setState({displayListViewBorder: true}) : this.setState({displayListViewBorder: false});
                 }}
             >
                 <GooglePlacesAutocomplete
@@ -130,9 +130,9 @@ class AddressSearch extends React.Component {
                     styles={{
                         textInputContainer: [styles.flexColumn],
                         listView: [
-                            this.state.displayDropdownBorder && styles.borderTopRounded,
-                            this.state.displayDropdownBorder && styles.borderBottomRounded,
-                            this.state.displayDropdownBorder && styles.mt1,
+                            this.state.displayListViewBorder && styles.borderTopRounded,
+                            this.state.displayListViewBorder && styles.borderBottomRounded,
+                            this.state.displayListViewBorder && styles.mt1,
                             styles.overflowAuto,
                             styles.borderLeft,
                             styles.borderRight,

From b90728a40bd235832264f6f64755848114876f19 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 14:54:43 -0600
Subject: [PATCH 07/18] componentDidMount to componentDidUpdate

---
 src/components/AddressSearch.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 5f8329fafe37..7bf4162aa385 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -45,7 +45,7 @@ class AddressSearch extends React.Component {
         this.googlePlacesRef = React.createRef();
     }
 
-    componentDidMount() {
+    componentDidUpdate() {
         if (!this.googlePlacesRef.current) {
             return;
         }

From bb496a6dd4b230b394eebe86257452c83c4dfc21 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 14:57:15 -0600
Subject: [PATCH 08/18] revert change

---
 src/components/AddressSearch.js | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 7bf4162aa385..ac991e1276cb 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -45,10 +45,10 @@ class AddressSearch extends React.Component {
         this.googlePlacesRef = React.createRef();
     }
 
-    componentDidUpdate() {
-        if (!this.googlePlacesRef.current) {
-            return;
-        }
+    componentDidMount() {
+        // if (!this.googlePlacesRef.current) {
+        //     return;
+        // }
 
         this.googlePlacesRef.current.setAddressText(this.props.value);
     }

From a6862893171dff4173af8dff4c2e3ebcdbfcb587 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 15:17:28 -0600
Subject: [PATCH 09/18] convert to functional component

---
 src/components/AddressSearch.js | 175 +++++++++++++++-----------------
 1 file changed, 83 insertions(+), 92 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index ac991e1276cb..2ba89e1d1c03 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -1,5 +1,5 @@
 import _ from 'underscore';
-import React from 'react';
+import React, {useEffect, useState, useRef} from 'react';
 import PropTypes from 'prop-types';
 import {LogBox, View} from 'react-native';
 import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
@@ -35,25 +35,18 @@ const defaultProps = {
     containerStyles: null,
 };
 
-class AddressSearch extends React.Component {
-    constructor(props) {
-        super(props);
-
-        this.state = {
-            displayListViewBorder: false,
-        };
-        this.googlePlacesRef = React.createRef();
-    }
-
-    componentDidMount() {
-        // if (!this.googlePlacesRef.current) {
-        //     return;
-        // }
+const AddressSearch = (props) => {
+    const googlePlacesRef = useRef();
+    const [display, setDisplay] = useState(false);
+    useEffect(() => {
+        if (!googlePlacesRef.current) {
+            return;
+        }
 
-        this.googlePlacesRef.current.setAddressText(this.props.value);
-    }
+        googlePlacesRef.current.setAddressText(props.value);
+    }, []);
 
-    saveLocationDetails(details) {
+    const saveLocationDetails = (details) => {
         const addressComponents = details.address_components;
         if (isAddressValidForVBA(addressComponents)) {
             // Gather the values from the Google details
@@ -68,10 +61,10 @@ class AddressSearch extends React.Component {
             const zipCode = getAddressComponent(addressComponents, 'postal_code', 'long_name');
 
             // Trigger text change events for each of the individual fields being saved on the server
-            this.props.onChangeText('addressStreet', `${streetNumber} ${streetName}`);
-            this.props.onChangeText('addressCity', city);
-            this.props.onChangeText('addressState', state);
-            this.props.onChangeText('addressZipCode', zipCode);
+            props.onChangeText('addressStreet', `${streetNumber} ${streetName}`);
+            props.onChangeText('addressCity', city);
+            props.onChangeText('addressState', state);
+            props.onChangeText('addressZipCode', zipCode);
         } else {
             // Clear the values associated to the address, so our validations catch the problem
             Log.hmmm('[AddressSearch] Search result failed validation: ', {
@@ -79,79 +72,77 @@ class AddressSearch extends React.Component {
                 address_components: addressComponents,
                 place_id: details.place_id,
             });
-            this.props.onChangeText('addressStreet', null);
-            this.props.onChangeText('addressCity', null);
-            this.props.onChangeText('addressState', null);
-            this.props.onChangeText('addressZipCode', null);
+            props.onChangeText('addressStreet', null);
+            props.onChangeText('addressCity', null);
+            props.onChangeText('addressState', null);
+            props.onChangeText('addressZipCode', null);
         }
-    }
-
-    render() {
-        return (
-
-            // We use the View height to determine if we should hide the border and margin of the listView dropdown
-            // to prevent a lingering border when there are no address suggestions
-            <View
-                onLayout={(event) => {
-                    const {height} = event.nativeEvent.layout;
-                    return height > 74 ? this.setState({displayListViewBorder: true}) : this.setState({displayListViewBorder: false});
+    };
+
+    return (
+
+        // We use the View height to determine if we should hide the border and margin of the listView dropdown
+        // to prevent a lingering border when there are no address suggestions
+        <View
+            onLayout={(event) => {
+                const {height} = event.nativeEvent.layout;
+                return height > 74 ? setDisplay(true) : setDisplay(false);
+            }}
+        >
+            <GooglePlacesAutocomplete
+                ref={googlePlacesRef}
+                fetchDetails
+                suppressDefaultStyles
+                enablePoweredByContainer={false}
+                onPress={(data, details) => saveLocationDetails(details)}
+                query={{
+                    key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
+                    language: props.preferredLocale,
+                    types: 'address',
+                    components: 'country:us',
                 }}
-            >
-                <GooglePlacesAutocomplete
-                    ref={this.googlePlacesRef}
-                    fetchDetails
-                    suppressDefaultStyles
-                    enablePoweredByContainer={false}
-                    onPress={(data, details) => this.saveLocationDetails(details)}
-                    query={{
-                        key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
-                        language: this.props.preferredLocale,
-                        types: 'address',
-                        components: 'country:us',
-                    }}
-                    requestUrl={{
-                        useOnPlatform: 'web',
-                        url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
-                    }}
-                    textInputProps={{
-                        InputComp: ExpensiTextInput,
-                        label: this.props.label,
-                        containerStyles: this.props.containerStyles,
-                        errorText: this.props.errorText,
-                        onChangeText: (text) => {
-                            const isTextValid = !_.isEmpty(text) && _.isEqual(text, this.props.value);
-
-                            // Ensure whether an address is selected already or has address value initialized.
-                            if (!_.isEmpty(this.googlePlacesRef.current.getAddressText()) && !isTextValid) {
-                                this.saveLocationDetails({});
-                            }
-                        },
-                    }}
-                    styles={{
-                        textInputContainer: [styles.flexColumn],
-                        listView: [
-                            this.state.displayListViewBorder && styles.borderTopRounded,
-                            this.state.displayListViewBorder && styles.borderBottomRounded,
-                            this.state.displayListViewBorder && styles.mt1,
-                            styles.overflowAuto,
-                            styles.borderLeft,
-                            styles.borderRight,
-                        ],
-                        row: [
-                            styles.pv4,
-                            styles.ph3,
-                            styles.overflowAuto,
-                        ],
-                        description: [styles.googleSearchText],
-                        separator: [styles.googleSearchSeparator],
-                    }}
-                />
-            </View>
-        );
-    }
-}
+                requestUrl={{
+                    useOnPlatform: 'web',
+                    url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
+                }}
+                textInputProps={{
+                    InputComp: ExpensiTextInput,
+                    label: props.label,
+                    containerStyles: props.containerStyles,
+                    errorText: props.errorText,
+                    onChangeText: (text) => {
+                        const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value);
+
+                        // Ensure whether an address is selected already or has address value initialized.
+                        if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) {
+                            saveLocationDetails({});
+                        }
+                    },
+                }}
+                styles={{
+                    textInputContainer: [styles.flexColumn],
+                    listView: [
+                        display && styles.borderTopRounded,
+                        display && styles.borderBottomRounded,
+                        display && styles.mt1,
+                        styles.overflowAuto,
+                        styles.borderLeft,
+                        styles.borderRight,
+                    ],
+                    row: [
+                        styles.pv4,
+                        styles.ph3,
+                        styles.overflowAuto,
+                    ],
+                    description: [styles.googleSearchText],
+                    separator: [styles.googleSearchSeparator],
+                }}
+            />
+        </View>
+    );
+};
 
 AddressSearch.propTypes = propTypes;
 AddressSearch.defaultProps = defaultProps;
 
-export default withLocalize(AddressSearch);
+export default withLocalize(AddressSearch);
\ No newline at end of file

From 10746c29c81950425eb0547662ba94969abcc6d2 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 15:22:13 -0600
Subject: [PATCH 10/18] adjust height

---
 src/components/AddressSearch.js | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 2ba89e1d1c03..d332872410d6 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -9,6 +9,7 @@ import styles from '../styles/styles';
 import ExpensiTextInput from './ExpensiTextInput';
 import Log from '../libs/Log';
 import {getAddressComponent, isAddressValidForVBA} from '../libs/GooglePlacesUtils';
+import display from '../styles/utilities/display';
 
 // The error that's being thrown below will be ignored until we fork the
 // react-native-google-places-autocomplete repo and replace the
@@ -37,7 +38,7 @@ const defaultProps = {
 
 const AddressSearch = (props) => {
     const googlePlacesRef = useRef();
-    const [display, setDisplay] = useState(false);
+    const [displayListViewBorder, setDisplayListViewBorder] = useState(false);
     useEffect(() => {
         if (!googlePlacesRef.current) {
             return;
@@ -82,11 +83,12 @@ const AddressSearch = (props) => {
     return (
 
         // We use the View height to determine if we should hide the border and margin of the listView dropdown
-        // to prevent a lingering border when there are no address suggestions
+        // to prevent a lingering border when there are no address suggestions. 
+        // The height of the input + error message is 94 pixels
         <View
             onLayout={(event) => {
                 const {height} = event.nativeEvent.layout;
-                return height > 74 ? setDisplay(true) : setDisplay(false);
+                return height > 94 ? setDisplayListViewBorder(true) : setDisplayListViewBorder(false);
             }}
         >
             <GooglePlacesAutocomplete
@@ -122,9 +124,9 @@ const AddressSearch = (props) => {
                 styles={{
                     textInputContainer: [styles.flexColumn],
                     listView: [
-                        display && styles.borderTopRounded,
-                        display && styles.borderBottomRounded,
-                        display && styles.mt1,
+                        displayListViewBorder && styles.borderTopRounded,
+                        displayListViewBorder && styles.borderBottomRounded,
+                        displayListViewBorder && styles.mt1,
                         styles.overflowAuto,
                         styles.borderLeft,
                         styles.borderRight,
@@ -145,4 +147,4 @@ const AddressSearch = (props) => {
 AddressSearch.propTypes = propTypes;
 AddressSearch.defaultProps = defaultProps;
 
-export default withLocalize(AddressSearch);
\ No newline at end of file
+export default withLocalize(AddressSearch);

From bff165e802b8e2327aaa704382b7e25de9fa59ae Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 15:23:42 -0600
Subject: [PATCH 11/18] fix style

---
 src/components/AddressSearch.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index d332872410d6..739a33201833 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -9,7 +9,6 @@ import styles from '../styles/styles';
 import ExpensiTextInput from './ExpensiTextInput';
 import Log from '../libs/Log';
 import {getAddressComponent, isAddressValidForVBA} from '../libs/GooglePlacesUtils';
-import display from '../styles/utilities/display';
 
 // The error that's being thrown below will be ignored until we fork the
 // react-native-google-places-autocomplete repo and replace the
@@ -83,7 +82,7 @@ const AddressSearch = (props) => {
     return (
 
         // We use the View height to determine if we should hide the border and margin of the listView dropdown
-        // to prevent a lingering border when there are no address suggestions. 
+        // to prevent a lingering border when there are no address suggestions.
         // The height of the input + error message is 94 pixels
         <View
             onLayout={(event) => {

From 20a6050bc00fa8d88eff0eacddd5fb77702462b7 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 16:20:30 -0600
Subject: [PATCH 12/18] add comment and adjust height;

---
 src/components/AddressSearch.js | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 739a33201833..4f8f7e35af2d 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -35,6 +35,9 @@ const defaultProps = {
     containerStyles: null,
 };
 
+// Do not convert to class component! setAddressText only works in functional components!
+// Reference: https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/609#issuecomment-886133839
+
 const AddressSearch = (props) => {
     const googlePlacesRef = useRef();
     const [displayListViewBorder, setDisplayListViewBorder] = useState(false);
@@ -87,7 +90,7 @@ const AddressSearch = (props) => {
         <View
             onLayout={(event) => {
                 const {height} = event.nativeEvent.layout;
-                return height > 94 ? setDisplayListViewBorder(true) : setDisplayListViewBorder(false);
+                return height > 112 ? setDisplayListViewBorder(true) : setDisplayListViewBorder(false);
             }}
         >
             <GooglePlacesAutocomplete

From ae573d5da90b7eaeeb7d2555a6192faeee701e29 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 16:21:17 -0600
Subject: [PATCH 13/18] update comment

---
 src/components/AddressSearch.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 4f8f7e35af2d..63cc2fa7fb9c 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -86,7 +86,7 @@ const AddressSearch = (props) => {
 
         // We use the View height to determine if we should hide the border and margin of the listView dropdown
         // to prevent a lingering border when there are no address suggestions.
-        // The height of the input + error message is 94 pixels
+        // The height of the input + wrapped error message is 112 pixels
         <View
             onLayout={(event) => {
                 const {height} = event.nativeEvent.layout;

From a018166eb5b8118c72cced68fe2e243a16685396 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 29 Oct 2021 16:22:44 -0600
Subject: [PATCH 14/18] remove line

---
 src/components/AddressSearch.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 63cc2fa7fb9c..6d60ec64b5c3 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -37,7 +37,6 @@ const defaultProps = {
 
 // Do not convert to class component! setAddressText only works in functional components!
 // Reference: https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/609#issuecomment-886133839
-
 const AddressSearch = (props) => {
     const googlePlacesRef = useRef();
     const [displayListViewBorder, setDisplayListViewBorder] = useState(false);

From 40b428fd779975e2bf1cefce077ecffd9bcdc972 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Mon, 1 Nov 2021 10:59:04 -0600
Subject: [PATCH 15/18] move height tracking to google component

---
 src/components/AddressSearch.js | 123 +++++++++++++++++---------------
 1 file changed, 65 insertions(+), 58 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 6d60ec64b5c3..a8ba3ff5879c 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -1,7 +1,7 @@
 import _ from 'underscore';
 import React, {useEffect, useState, useRef} from 'react';
 import PropTypes from 'prop-types';
-import {LogBox, View} from 'react-native';
+import {LogBox} from 'react-native';
 import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
 import CONFIG from '../CONFIG';
 import withLocalize, {withLocalizePropTypes} from './withLocalize';
@@ -35,7 +35,8 @@ const defaultProps = {
     containerStyles: null,
 };
 
-// Do not convert to class component! setAddressText only works in functional components!
+// Do not convert to class component! It's been tried before and presents more challenges than it's worth.
+// Relevant thread: https://expensify.slack.com/archives/C03TQ48KC/p1634088400387400
 // Reference: https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/609#issuecomment-886133839
 const AddressSearch = (props) => {
     const googlePlacesRef = useRef();
@@ -82,66 +83,72 @@ const AddressSearch = (props) => {
     };
 
     return (
+        <GooglePlacesAutocomplete
+            ref={googlePlacesRef}
+            fetchDetails
+            suppressDefaultStyles
+            enablePoweredByContainer={false}
+            onPress={(data, details) => {
+                saveLocationDetails(details);
 
-        // We use the View height to determine if we should hide the border and margin of the listView dropdown
-        // to prevent a lingering border when there are no address suggestions.
-        // The height of the input + wrapped error message is 112 pixels
-        <View
+                // After we select an option, we set displayListViewBorder to false to prevent UI flickering
+                setDisplayListViewBorder(false);
+            }}
+            query={{
+                key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
+                language: props.preferredLocale,
+                types: 'address',
+                components: 'country:us',
+            }}
+            requestUrl={{
+                useOnPlatform: 'web',
+                url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
+            }}
+            textInputProps={{
+                InputComp: ExpensiTextInput,
+                label: props.label,
+                containerStyles: props.containerStyles,
+                errorText: props.errorText,
+                onChangeText: (text) => {
+                    const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value);
+
+                    // Ensure whether an address is selected already or has address value initialized.
+                    if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) {
+                        saveLocationDetails({});
+                    }
+
+                    // If the text is empty, we set displayListViewBorder to false to prevent UI flickering
+                    if (_.isEmpty(text)) {
+                        setDisplayListViewBorder(false);
+                    }
+                },
+            }}
+            styles={{
+                textInputContainer: [styles.flexColumn],
+                listView: [
+                    displayListViewBorder && styles.borderTopRounded,
+                    displayListViewBorder && styles.borderBottomRounded,
+                    displayListViewBorder && styles.mt1,
+                    styles.overflowAuto,
+                    styles.borderLeft,
+                    styles.borderRight,
+                ],
+                row: [
+                    styles.pv4,
+                    styles.ph3,
+                    styles.overflowAuto,
+                ],
+                description: [styles.googleSearchText],
+                separator: [styles.googleSearchSeparator],
+            }}
             onLayout={(event) => {
+                // We use the height of the element to determine if we should hide the border of the listView dropdown
+                // to prevent a lingering border when there are no address suggestions.
+                // The height of the empty element is 2px (1px height for each top and bottom borders)
                 const {height} = event.nativeEvent.layout;
-                return height > 112 ? setDisplayListViewBorder(true) : setDisplayListViewBorder(false);
+                setDisplayListViewBorder(height > 2);
             }}
-        >
-            <GooglePlacesAutocomplete
-                ref={googlePlacesRef}
-                fetchDetails
-                suppressDefaultStyles
-                enablePoweredByContainer={false}
-                onPress={(data, details) => saveLocationDetails(details)}
-                query={{
-                    key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
-                    language: props.preferredLocale,
-                    types: 'address',
-                    components: 'country:us',
-                }}
-                requestUrl={{
-                    useOnPlatform: 'web',
-                    url: `${CONFIG.EXPENSIFY.URL_EXPENSIFY_COM}api?command=Proxy_GooglePlaces&proxyUrl=`,
-                }}
-                textInputProps={{
-                    InputComp: ExpensiTextInput,
-                    label: props.label,
-                    containerStyles: props.containerStyles,
-                    errorText: props.errorText,
-                    onChangeText: (text) => {
-                        const isTextValid = !_.isEmpty(text) && _.isEqual(text, props.value);
-
-                        // Ensure whether an address is selected already or has address value initialized.
-                        if (!_.isEmpty(googlePlacesRef.current.getAddressText()) && !isTextValid) {
-                            saveLocationDetails({});
-                        }
-                    },
-                }}
-                styles={{
-                    textInputContainer: [styles.flexColumn],
-                    listView: [
-                        displayListViewBorder && styles.borderTopRounded,
-                        displayListViewBorder && styles.borderBottomRounded,
-                        displayListViewBorder && styles.mt1,
-                        styles.overflowAuto,
-                        styles.borderLeft,
-                        styles.borderRight,
-                    ],
-                    row: [
-                        styles.pv4,
-                        styles.ph3,
-                        styles.overflowAuto,
-                    ],
-                    description: [styles.googleSearchText],
-                    separator: [styles.googleSearchSeparator],
-                }}
-            />
-        </View>
+        />
     );
 };
 

From 191cbbce03f43126b4593ad992f282a77877aa7f Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Mon, 1 Nov 2021 12:52:46 -0600
Subject: [PATCH 16/18] remove destructuring

---
 src/components/AddressSearch.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index a8ba3ff5879c..c9631ccd2709 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -145,8 +145,7 @@ const AddressSearch = (props) => {
                 // We use the height of the element to determine if we should hide the border of the listView dropdown
                 // to prevent a lingering border when there are no address suggestions.
                 // The height of the empty element is 2px (1px height for each top and bottom borders)
-                const {height} = event.nativeEvent.layout;
-                setDisplayListViewBorder(height > 2);
+                setDisplayListViewBorder(event.nativeEvent.layout.height > 2);
             }}
         />
     );

From 0db98c5b96427341e6de6d5481a1e77424ba67e9 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Mon, 1 Nov 2021 13:14:52 -0600
Subject: [PATCH 17/18] remove flickering

---
 src/components/AddressSearch.js | 1 +
 src/styles/styles.js            | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index c9631ccd2709..158e3829779b 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -126,6 +126,7 @@ const AddressSearch = (props) => {
             styles={{
                 textInputContainer: [styles.flexColumn],
                 listView: [
+                    !displayListViewBorder && styles.googleListView,
                     displayListViewBorder && styles.borderTopRounded,
                     displayListViewBorder && styles.borderBottomRounded,
                     displayListViewBorder && styles.mt1,
diff --git a/src/styles/styles.js b/src/styles/styles.js
index 4488a4643d4a..39d573fa31a1 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -2108,6 +2108,10 @@ const styles = {
         fontFamily: fontFamily.GTA,
         flex: 1,
     },
+
+    googleListView: {
+        transform: [{scale: 0}],
+    }
 };
 
 const baseCodeTagStyles = {

From 6ecacd572f88b18ad7d96b75dec8493a5bab5a5b Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Mon, 1 Nov 2021 13:19:51 -0600
Subject: [PATCH 18/18] fix style

---
 src/styles/styles.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/styles/styles.js b/src/styles/styles.js
index 39d573fa31a1..8ba0faae2143 100644
--- a/src/styles/styles.js
+++ b/src/styles/styles.js
@@ -2111,7 +2111,7 @@ const styles = {
 
     googleListView: {
         transform: [{scale: 0}],
-    }
+    },
 };
 
 const baseCodeTagStyles = {
