JSPM

  • Created
  • Published
  • Downloads 161924
  • Score
    100M100P100Q170097F
  • License MIT

React hook for Google Maps Places Autocomplete.

Package Exports

  • use-places-autocomplete

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (use-places-autocomplete) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

🚧 This project is under developing, API MAY CHANGED FREQUENTLY, PLEASE DON'T USE IT NOW ✋🏻. Here's my milestone.

usePlacesAutocomplete

This is a React hook of Google Maps Places Autocomplete, which helps you build an UI component with the feature of place autocomplete easily! By leverage the power of Google Maps Places API, you can provide a great UX (user experience) for user interacts with your search bar or form etc.

⚡️ Live demo: https://use-places-autocomplete.netlify.com

build status coverage status npm version npm downloads npm downloads npm bundle size MIT licensed All Contributors PRs welcome Twitter URL

Milestone

  • usePlacesAutocomplete hook
  • Useful utils, e.g. geocoding etc.
  • Server-side rendering friendly
  • Built-in autocomplete UI component (maybe...)
  • Unit testing
  • Demo app
  • Documentation
  • Typescript type definition
  • CI/CD

Requirement

To use use-places-autocomplete, you must use react@16.8.0 or greater which includes hooks.

Installation

This package is distributed via npm.

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

Usage Preview (demo)

This is my currently idea of how does it work, it still unstable. So, I don't suggest you use it now. But welcome to preview or play it and feel free to give me suggestion 🤔

Before we start

To use this hook, there're two things we need to do:

  1. Enable Google Maps Places API.
  2. Get an API key.

Load the library

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>

We also support asynchronous script loading. By doing so you need to pass the initMap as the callbackName option.

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

⚠️ If you got a global function not found error. Make sure usePlaceAutocomplete is declared before the script is loaded.

Create the component

Now we can start rock'n roll our component. You can check the API section to learn more.

import usePlacesAutocomplete from 'use-places-autocomplete';
import useOnclickOutside from 'react-cool-onclickoutside';

const PlacesAutocomplete = props => {
  const {
    ready,
    value,
    suggestions: { status, data },
    setValue,
    clearSuggestions
  } = usePlacesAutocomplete({
    requestOptions: { /* Define search scope here */ }
    debounce: 300
  });
  const registerRef = useOnclickOutside(() => {
    clearSuggestions();
  });

  const handleInput = e => {
    setValue(e.target.value);
  };

  const handleSelect = ({ description }) => () => {
    setValue(description, false);
    clearSuggestions();

    // Do something you want...
  };

  const renderSuggestions = () =>
    data.map(suggestion => (
      <li
        key={suggestion.id}
        onClick={handleSelect(suggestion)}
        role="presentation"
      >
        {suggestion.description}
      </li>
    ));

  return (
    <div ref={registerRef}>
      <input
        value={value}
        onChange={handleInput}
        placeholder="Enter a place"
        type="text"
        disabled={!ready}
      />
      {value !== '' && status === 'OK' && <ul>{renderSuggestions()}</ul>}
    </div>
  );
};

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

API

const return = usePlacesAutocomplete(parameter);

Parameter (optional)

When use usePlacesAutocomplete you can configure the following options by pass an object as the parameter.

Key Type (all optional) Default Description
requestOptions object The request options of Google Maps Places API except for input (e.g. bounds, radius etc.).
googleMaps object window.google.maps In case you want to provide your own Google Maps object, pass it in as google.maps.
callbackName string You can provide a callback name to initialize usePlacesAutocomplete after Google script is loaded. It's useful when you load the script asynchronously.
debounce number 200 Number of milliseconds to delay before making a request to Google Maps Places API.

Return

It's an object that returned with the following properties.

Key Type Default Description
ready boolean false The ready status of usePlacesAutocomplete.
value string '' value for the input element.
suggestions object { loading: false, status: '', data: [] } See suggestions.
setValue function (value, shouldFetchData = true) => {} See setValue.
clearSuggestions function See clearSuggestions.

suggestions

The search result of Google Maps Places API, which contains the following properties:

  • loading: boolean - indicates the status of a request is pending or has completed. It's useful for displaying a loading indicator for user.
  • status: string - indicates the status of PlacesService (docs). It's useful to decide whether we should display the suggestions panel or not.
  • data: array - an array of suggestion objects each contains all the data as AutocompletePrediction (docs).

setValue

Set the value of the input element. Use case as below.

import usePlacesAutocomplete from 'use-places-autocomplete';

const PlacesAutocomplete = props => {
  const { value, setValue } = usePlacesAutocomplete();

  const handleInput = e => {
    // Place a "string" to update the value of the input element
    setValue(e.target.value);
  };

  return (
    <div>
      <input value={value} onChange={handleInput} type="text" />
      {/* Render suggestions panel */}
    </div>
  );
};

In addition, the setValue method has an extra parameter, which can be used to disable hitting Google Maps Places API.

import usePlacesAutocomplete from 'use-places-autocomplete';

const PlacesAutocomplete = props => {
  const { value, suggestions, setValue } = usePlacesAutocomplete();

  const handleSelect = description => () => {
    // When user select a place, we can update the keyword without request data from API
    // by set the second parameter to "false"
    setValue(description, false);
  };

  const renderSuggestions = () =>
    suggestions.data.map(({ id, description }) => (
      <li key={id} onClick={handleSelect(description)} role="presentation">
        {description}
      </li>
    ));

  return (
    <div>
      <input value={value} onChange={handleInput} type="text" />
      <ul>{renderSuggestions()}</ul>
    </div>
  );
};

clearSuggestions

Coming soon...

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Welly

💻 📖 🚧

This project follows the all-contributors specification. Contributions of any kind welcome!