loading...

✨ Introducing use-places-autocomplete: React hook for Google Maps Places Autocomplete

wellyshen profile image Welly Updated on ・3 min read

Yooo guys! with use-places-autocomplete you can build your own places autocomplete UI like the following demo in 10 minutes, no kidding 😉

demo

⚡️ Try yourself: https://use-places-autocomplete.netlify.app

Features

How does it work?

First, use the script tag to load the library in your project.

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>

Start to build our component. Check the API out to learn more.

import React from "react";
import usePlacesAutocomplete, {
  getGeocode,
  getLatLng,
} from "use-places-autocomplete";
import useOnclickOutside from "react-cool-onclickoutside";

const PlacesAutocomplete = () => {
  const {
    ready,
    value,
    suggestions: { status, data },
    setValue,
    clearSuggestions,
  } = usePlacesAutocomplete({
    requestOptions: {
      /* Define search scope here */
    },
    debounce: 300,
  });
  const ref = useOnclickOutside(() => {
    // When user clicks outside of the component, we can dismiss
    // the searched suggestions by calling this method
    clearSuggestions();
  });

  const handleInput = (e) => {
    // Update the keyword of the input element
    setValue(e.target.value);
  };

  const handleSelect = ({ description }) => () => {
    // When user selects a place, we can replace the keyword without request data from API
    // by setting the second parameter as "false"
    setValue(description, false);
    clearSuggestions();

    // Get latitude and longitude via utility functions
    getGeocode({ address: description })
      .then((results) => getLatLng(results[0]))
      .then(({ lat, lng }) => {
        console.log("📍 Coordinates: ", { lat, lng });
      })
      .catch((error) => {
        console.log("😱 Error: ", error);
      });
  };

  const renderSuggestions = () =>
    data.map((suggestion) => {
      const {
        id,
        structured_formatting: { main_text, secondary_text },
      } = suggestion;

      return (
        <li key={id} onClick={handleSelect(suggestion)}>
          <strong>{main_text}</strong> <small>{secondary_text}</small>
        </li>
      );
    });

  return (
    <div ref={ref}>
      <input
        value={value}
        onChange={handleInput}
        disabled={!ready}
        placeholder="Where are you going?"
      />
      {/* We can use the "status" to decide whether we should display the dropdown or not */}
      {status === "OK" && <ul>{renderSuggestions()}</ul>}
    </div>
  );
};

Easy right? This is the magic of the usePlacesAutocomplete ✨. I just show you how does it work via the minimal example. However there're more things you can do for an UX rich autocomplete component, like WAI-ARIA compliant and keyword support as my demo (check the code), a keyword clear button, search history etc.

💡 react-cool-onclickoutside is my other hook library, which can help you handle the interaction of user clicks outside of the component(s).


Thanks for reading, for more usage details checkout the project's GitHub page: https://github.com/wellyshen/use-places-autocomplete

You can also install this package is distributed via npm.

$ yarn add use-places-autocomplete
# or
$ npm install --save use-places-autocomplete

Posted on by:

Discussion

pic
Editor guide
 

hi, thanks for this amazing hook
I have a question, How can i integrate this hook with useScript -usehooks.com/useScript/
to load google map script asyncly?
I get below error

'> 💡use-places-autocomplete: Google Maps Places API library must be loaded. See: github.com/wellyshen/use-places-au...';

 

I am getting the same error, has anyone found a solution for this?

 

Hi Welly, this is really nicely designed! One concern though, you're using a script tag to bring in the google maps api, but that exposes the API key to the user. Any ideas on how to keep the key safe?

 

Google has provided many way to limit the usage of the API key. You can configure it via Google Cloud Console (console.cloud.google.com)

 

Hey Welly that's cool! But do you know if I can use it with Gatsby(a react based language)?

 

Sometimes the "ready" is false, so the input is disabled. How to solve this problem?

 

Can you give me an open issue with a minimal reproduced repo, thank you.