Forked from WillMayger/how-to-use-google-autocomplete-with-react-hooks.js
Created
October 3, 2021 01:09
-
-
Save michaelchen753/c2554a3a22669d8ab983b59da52757f1 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