How To Use Google Places API In React
React
30/01/2023
Before you can use the Google Places API, you first need to ensure that the API is enabled.
Loading the library
To load the API library, I recommend using a custom hook, in particular 👉 this example. For the TypeScript lovers, you're covered as well.
In your Google Places Input, i.e. AutoComplete component, call the hook with the link below. Make sure to replace YOUR_KEY
with the API key retrieved during the setup earlier.
const scriptStatus = useScript( // By default, Google Places will attempt to guess your language based on your country. // However, you may specify it explicitly with the `language` parameter. `https://maps.googleapis.com/maps/api/js?language=en&key=${YOUR_KEY}&libraries=places`)
Creating the AutoComplete component
In the Autocomplete component, we maintain 2 refs:
- One is of the component itself, which will contain the Google Places AutoComplete class, and
- The other is of the input field, inside the component, which Google Places uses to automatically 🙌 add dropdown options upon user input.
const autoCompleteRef = useRef<google.maps.places.AutoComplete>()const inputRef = useRef<HTMLInputElement>()
// Some code in the next example.
return <input ref={inputRef} />
Following that, a useEffect
hook will take care of the ref setup, including data fetching. It should only run once upon the component mounting, hence the various checks 💂♂️ in the beginning.
What you should pay attention to is the initialization of the AutoComplete
class, which accepts a reference to the input field and an options object. The latter allows you to apply restrictions such as countries and types of locations as well as the type of data you wish to receive.
Moreover, an anonymous function listens to the event place_changed
, which occurs whenever a user selects a location from the Google Places generated dropdown.
const options = useMemo( () => ({ componentRestrictions: { country: "at" }, fields: ["address_components", "geometry", "name"], types: ["establishment"], }), [])
useEffect(() => { // Conditions to ensure that no multiple instances of the // Google Places API class and event listener exist. if ( autoCompleteRef.current || scriptStatus === "loading" || !inputRef.current || !window.google || !window.google.maps || !window.google.maps.places ) { return }
if (scriptStatus === "error") { // Report error return }
autoCompleteRef.current = new window.google.maps.places.AutoComplete( inputRef.current, options )
autoCompleteRef.current.addListener("place_changed", () => { if (!autoCompleteRef.current) { return }
// Retrieve the selected location with the `getPlace` method. onChange(autoCompleteRef.current.getPlace()) })}, [scriptStatus, options, onChange])
In this code example, onChange
is simply a useState
function that's passed in ⬇ from the parent component.
Gotcha
Lastly, you may want to set the value from the input field to null
on any key stroke to ensure that only values retrieved by the API are accepted. For instance, the user may remove their selection or accidentally delete a character or two in the field.
<input ref={inputRef}+ onChange={() => onChange(null)} />)