Created
July 11, 2019 19:58
-
-
Save codyeatworld/793fa3e9bf25afaddd1675fb914542c1 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/* eslint-disable no-undef */ | |
import { useEffect, useState, useRef } from 'react'; | |
const useAutocomplete = () => { | |
// By using the `set` method of the `useState` hook, we can coax this into being `callback ref` | |
// contained inside of the hook. | |
const [autocompleteRef, setAutocompleteRef] = useState(null); | |
// We will return the formatted address with this const. | |
const [autocompletedAddress, setAutocompletedAddress] = useState(null); | |
// We only want one instance of the google places autocomplete method called using our callback | |
// ref. We can use a ref to store this instance across renders. | |
const autocomplete = useRef(); | |
useEffect(() => { | |
// Since the autocompleteRef can be null, we need to make sure its ready. | |
if (autocompleteRef) { | |
// Use this listener callback to format an address object when the user selects an address | |
// from the autocomplete dropdown. | |
const onPlaceChanged = (ac) => () => { | |
// Get selected address results | |
const components = ac.getPlace().address_components; | |
// Initialize new address object | |
const address = {}; | |
// Address type/name mapping | |
const mapping = { | |
street_number: 'short_name', | |
route: 'long_name', | |
locality: 'long_name', | |
administrative_area_level_1: 'short_name', | |
postal_code: 'short_name', | |
}; | |
// Format address values using mapping and results. | |
for (let i = 0; i < components.length; i++) { | |
const type = components[i].types[0]; | |
if (mapping[type]) { | |
const value = components[i][mapping[type]]; | |
address[type] = value; | |
} | |
}; | |
// Set autocompleted/formatted address. | |
setAutocompletedAddress(address); | |
}; | |
// Initialize google maps | |
autocomplete.current = new google.maps.places.Autocomplete( | |
autocompleteRef, | |
{ | |
types: ['address'], | |
}, | |
); | |
autocomplete.current.setFields(['address_component']); | |
autocomplete.current.addListener('place_changed', onPlaceChanged(autocomplete.current)); | |
} | |
}, [autocompleteRef]); | |
// Return ref and address. | |
// We can react to the autocompletedAddress whenever it changes to do something with it. | |
// This allows this hook to be used on any form! | |
return [setAutocompleteRef, autocompletedAddress]; | |
}; | |
export default useAutocomplete; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment