Last active
February 9, 2022 10:27
-
-
Save WillMayger/6db35a1678c26efe7a6e19921a8a312b to your computer and use it in GitHub Desktop.
Gist containing all the code for the article: https://atomizedobjects.com/blog/react/how-to-use-google-autocomplete-with-react-hooks/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Script tag to include in <head>: | |
<script | |
type="text/javascript" | |
src="//maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_GOES_HERE&language=en&libraries=places" | |
></script> | |
import React, { useState, useEffect } from "react" | |
// Async google places autocomplete function | |
export const googleAutocomplete = async text => | |
new Promise((resolve, reject) => { | |
if (!text) { | |
return reject("Need valid text input") | |
} | |
// for use in things like GatsbyJS where the html is generated first | |
if (typeof window === "undefined") { | |
return reject("Need valid window object") | |
} | |
try { | |
new window.google.maps.places.AutocompleteService().getPlacePredictions( | |
{ input: text, componentRestrictions: { country: "gb" } }, | |
resolve | |
) | |
} catch (e) { | |
reject(e) | |
} | |
}) | |
// React component that uses the auto complete function | |
export function PredictionsOnFormSubmission() { | |
const [searchValue, setSearchValue] = useState("") | |
const [predictions, setPredictions] = useState([]) | |
const handleSubmit = async e => { | |
e.preventDefault() | |
const results = await googleAutocomplete(searchValue) | |
if (results) { | |
setPredictions(results) | |
} | |
} | |
return ( | |
<> | |
<form onSubmit={handleSubmit}> | |
<input | |
name="predictionSearch" | |
value={searchValue} | |
onChange={e => setSearchValue(e.target.value)} | |
/> | |
<button type="submit">Search</button> | |
</form> | |
<img | |
src="https://developers.google.com/maps/documentation/images/powered_by_google_on_white.png" | |
alt="Powered by Google" | |
/> | |
{predictions?.map(prediction => ( | |
<p key={prediction?.place_id}> | |
{prediction?.structured_formatting?.main_text || "Not found"} | |
</p> | |
))} | |
</> | |
) | |
} | |
// Google places autocomplete react hook | |
import { useState, useEffect } from 'react' | |
// the function we just created | |
import { googleAutocomplete } from './google-autocomplete' | |
export function usePlacesAutocomplete(text = "", debounceTimeout = 400) { | |
const [predictions, setPredictions] = useState([]) | |
useEffect(() => { | |
const handleDebounce = setTimeout(async () => { | |
try { | |
if (!text) { | |
return | |
} | |
const nextPredictions = await googleAutocomplete(text) | |
setPredictions(nextPredictions) | |
} catch (e) { | |
console.error(e) | |
} | |
}, debounceTimeout) | |
return () => { | |
clearTimeout(handleDebounce) | |
} | |
}, [text, debounceTimeout]) | |
return predictions | |
} | |
// Using the react hook in a function example | |
export function PredictionsOnInputChange() { | |
const [selectedPrediction, setSelectedPrediction] = useState(null) | |
const [searchValue, setSearchValue] = useState("") | |
const predictions = usePlacesAutocomplete(searchValue) | |
const handlePredictionSelection = (e, prediction) => { | |
e.preventDefault() | |
setSelectedPrediction(prediction) | |
} | |
return ( | |
<> | |
<form> | |
<input | |
name="predictionSearch" | |
value={searchValue} | |
onChange={e => setSearchValue(e.target.value)} | |
/> | |
<img | |
src="https://developers.google.com/maps/documentation/images/powered_by_google_on_white.png" | |
alt="Powered by Google" | |
/> | |
<ul> | |
{predictions?.map(prediction => ( | |
<li key={prediction?.place_id}> | |
<button | |
onClick={e => handlePredictionSelection(e, prediction)} | |
onKeyDown={e => handlePredictionSelection(e, prediction)} | |
> | |
{prediction?.structured_formatting?.main_text || "Not found"} | |
</button> | |
</li> | |
))} | |
</ul> | |
<h3>You searched for: {searchValue}</h3> | |
<h3> | |
You selected:{" "} | |
{selectedPrediction?.structured_formatting?.main_text || "None"} | |
</h3> | |
</form> | |
</> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Gist for all the code in the article How to make and use a Google autocomplete react hook