How to Add Address Autocomplete in React Native (Google Places Example)

How to Add Google Places Autocomplete in React Native?

  • Adding an address or location input with suggestions is common for delivery apps, booking, and user profiles.
  • The react-native-google-places-autocomplete package provides a powerful autocomplete experience for addresses and places.
  • As users type, the component calls the Google Places API and shows live suggestions.
  • You can fetch full address details, postal code, coordinates, and more on selection.

GooglePlacesInput Component Example

GooglePlacesInput.tsx
import React, { createRef, useEffect } from 'react';
import { DimensionValue, StyleSheet, TextInputProps, View } from 'react-native';
import {
  GooglePlaceData,
  GooglePlaceDetail,
  GooglePlacesAutocomplete,
  GooglePlacesAutocompleteRef,
} from 'react-native-google-places-autocomplete';
import { Colors } from '@/theme';
import { resolveFontFamily } from '@/theme/fonts';
import { Shadows } from '@/theme/shadows';
import { AppInputLabel } from '../text/AppInputLabel';
import { InputStyles } from '@/theme/InputStyles';
import { Address } from '@/model/address/types';
import { AppText } from '../text/AppText';

type OnPressHandler = (data: GooglePlaceData, detail: GooglePlaceDetail | null) => void;

export type WHTextInputProps = {
  labelFontColor?: string;
  label?: string;
  onAddressChange: (data: Partial<Address>) => void;
  placeholder?: string;
  onChangeText?: (v: string) => void;
  width?: DimensionValue | undefined;
};

const GOOGLE_PLACES_API_KEY = '';

export const googlePlacesInputRef = createRef<GooglePlacesAutocompleteRef>();

const GooglePlacesInput = (props: WHTextInputProps & TextInputProps) => {
  const {
    labelFontColor,
    label,
    value,
    onAddressChange,
    placeholder = '',
    onChangeText = () => {},
    width = '100%',
  } = props;

  useEffect(() => {
    value && googlePlacesInputRef.current?.setAddressText(value);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handlePress: OnPressHandler = (_, details) => {
    const route = details?.address_components.find((addressComponent) =>
      addressComponent.types.includes('street_number')
    )?.short_name;
    const streetNumber = details?.address_components.find((addressComponent) =>
      addressComponent.types.includes('route')
    )?.short_name;
    const streetOne = `${route ? route : ''} ${streetNumber}`;
    const postalCode = details?.address_components.find((addressComponent) =>
      addressComponent.types.includes('postal_code')
    )?.short_name;
    const city = details?.address_components.find((addressComponent) =>
      addressComponent.types.includes('locality')
    )?.long_name;
    const state = details?.address_components.find((addressComponent) =>
      addressComponent.types.includes('administrative_area_level_1')
    )?.short_name;
    const country = details?.address_components.find((addressComponent) =>
      addressComponent.types.includes('country')
    )?.short_name;
    const coordinates = details?.geometry.location as unknown as {
      lat: number;
      lng: number;
    };
    const data: Partial<Address> = {
      streetOne,
      postalCode,
      city,
      state,
      latitude: coordinates.lat,
      longitude: coordinates.lng,
      country,
    };
    onAddressChange(data);
  };

  return (
    <View style={{ width }}>
      {label && <AppInputLabel label={label} color={labelFontColor} />}
      <GooglePlacesAutocomplete
        ref={googlePlacesInputRef}
        placeholder={placeholder}
        fetchDetails
        enablePoweredByContainer
        onPress={handlePress}
        query={{
          key: GOOGLE_PLACES_API_KEY,
          language: 'en',
          types: 'address',
        }}
        textInputProps={{
          placeholderTextColor: Colors.Grey,
          returnKeyType: 'next',
          onChangeText,
        }}
        styles={{
          textInput: {
            ...InputStyles.primary,
            fontFamily: resolveFontFamily('400'),
          },
          container: styles.container,
          listView: styles.listView,
        }}
        disableScroll={true}
        renderRow={(rowData) => {
          const title = rowData.structured_formatting.main_text;
          const address = rowData.structured_formatting.secondary_text;
          return (
            <View>
              <AppText>{title}</AppText>
              <AppText>{address}</AppText>
            </View>
          );
        }}
      />
    </View>
  );
};

export default GooglePlacesInput;

const styles = StyleSheet.create({
  container: {},
  textInputContainer: {
    backgroundColor: '#ffffff',
    borderRadius: 10,
    justifyContent: 'flex-start',
    zIndex: 10,
    height: 50,
    alignItems: 'center',
    ...Shadows.xs,
  },
  listView: {
    borderRadius: 5,
    backgroundColor: Colors.White,
    borderWidth: 1,
    borderColor: Colors.LightGrey,
    ...Shadows.xs,
  },
  separator: {
    display: 'none',
  },
});
  • GooglePlacesInput is a reusable component for entering and selecting addresses.
  • Supports custom label, placeholder, and styles for seamless form integration.
  • Uses an onPress handler to extract and format all needed address parts: street, city, state, postal code, country, and coordinates.
  • Works well inside ScrollView and forms, and is fully customizable for UI/UX needs.
  • Address suggestions appear as you type, and the component fetches additional data like latitude and longitude on selection.

Key Takeaways

  • Google Places Autocomplete provides instant address suggestions in React Native apps.
  • You can extract street, city, postal code, state, country, and geo coordinates from the selected address.
  • This approach works great for delivery forms, profile setup, checkout, or any feature that needs a location input.
  • All autocomplete logic is handled for you, making UX smooth and error-resistant.

Hey! If you're enjoying this content, I write regularly about building apps with React Native, Expo, Firebase, and modern frontend tools.
👉 Join my newsletter here

I'm Matt — a Senior React Native developer with 6+ years of experience. I've shipped over 30 web and mobile apps, led dev teams, and specialize in launching MVPs fast using tools like Expo, TypeScript, Firebase, and AI. Whether it's B2B SaaS, marketplaces, or social platforms, I've probably built something like it.

Have a Product in Mind?

We help founders and small teams turn product ideas into working apps. Send us a message—we’d love to hear what you're building.