Skip to content

Instantly share code, notes, and snippets.

@jeremy-code
Created August 7, 2022 21:08
Show Gist options
  • Save jeremy-code/ab54ac904ec3a9cb1cebd61669830e88 to your computer and use it in GitHub Desktop.
Save jeremy-code/ab54ac904ec3a9cb1cebd61669830e88 to your computer and use it in GitHub Desktop.
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