Created
August 7, 2022 21:08
-
-
Save jeremy-code/ab54ac904ec3a9cb1cebd61669830e88 to your computer and use it in GitHub Desktop.
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
import React, { useCallback, useEffect, useRef } from "react"; | |
import { useForm } from "react-hook-form"; | |
import useScript from "../hooks/useScript"; | |
type LocationFormData = { | |
location: string; | |
}; | |
const AutocompleteInput = () => { | |
// Load the Google Maps API script asynchronously | |
const status = useScript( | |
`https://maps.googleapis.com/maps/api/js?key=${ | |
import.meta.env.VITE_GOOGLE_MAPS_API_KEY | |
}&libraries=places` | |
); | |
const inputRef = useRef<HTMLInputElement | null>(null); | |
// Create a ref to hold the Google Maps autocomplete object | |
const autocompleteRef = useRef<google.maps.places.Autocomplete | null>(null); | |
const { handleSubmit, register } = useForm<LocationFormData>(); | |
// split up location input into its ref and everything else | |
const { ref, ...rest } = register("location", { | |
required: "This is required", | |
pattern: { | |
value: /\w+, USA$/, | |
message: "Please enter a valid location", | |
}, | |
}); | |
// Create an instance of the autocomplete object and store it in ref | |
const createNewAutocomplete = useCallback( | |
(inputRef: React.RefObject<HTMLInputElement>) => { | |
if (!inputRef.current) return; | |
const autocomplete = new google.maps.places.Autocomplete( | |
inputRef.current, | |
{ | |
types: ["(cities)"], | |
componentRestrictions: { country: "us" }, | |
} | |
); | |
autocomplete.setFields(["geometry", "formatted_address"]); | |
autocompleteRef.current = autocomplete; | |
}, | |
[] | |
); | |
// Whenever the status changes and the status of the script is set to ready, | |
// create a new autocomplete object | |
useEffect(() => { | |
status === "ready" && createNewAutocomplete(inputRef); | |
}, [status]); | |
const onSubmit = (data: LocationFormData) => { | |
const place = autocompleteRef.current?.getPlace(); | |
console.log(place?.geometry?.location?.toString()); | |
console.table(data); | |
}; | |
return ( | |
<form onSubmit={handleSubmit(onSubmit)}> | |
<input | |
{...rest} | |
// retrieve the input ref from the ref object | |
ref={(e: HTMLInputElement | null) => { | |
ref(e); | |
inputRef.current = e; | |
}} | |
/> | |
<button type="submit"> Submit </button> | |
</form> | |
); | |
}; | |
export default AutocompleteInput; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment