Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
react-places-autocomplete
Advanced tools
The react-places-autocomplete package is a React component that provides an easy way to integrate Google Places Autocomplete functionality into your React applications. It allows users to search for places and addresses with autocomplete suggestions powered by the Google Places API.
Basic Autocomplete
This feature allows users to input a location and get autocomplete suggestions. When a suggestion is selected, it fetches the geocode and latitude/longitude of the selected place.
import React, { useState } from 'react';
import PlacesAutocomplete, { geocodeByAddress, getLatLng } from 'react-places-autocomplete';
function LocationSearchInput() {
const [address, setAddress] = useState('');
const [coordinates, setCoordinates] = useState({ lat: null, lng: null });
const handleSelect = async value => {
const results = await geocodeByAddress(value);
const latLng = await getLatLng(results[0]);
setAddress(value);
setCoordinates(latLng);
};
return (
<PlacesAutocomplete
value={address}
onChange={setAddress}
onSelect={handleSelect}
>
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div>
<input {...getInputProps({ placeholder: 'Search Places ...' })} />
<div>
{loading && <div>Loading...</div>}
{suggestions.map(suggestion => {
const style = suggestion.active
? { backgroundColor: '#a8dadc', cursor: 'pointer' }
: { backgroundColor: '#ffffff', cursor: 'pointer' };
return (
<div {...getSuggestionItemProps(suggestion, { style })}>
{suggestion.description}
</div>
);
})}
</div>
</div>
)}
</PlacesAutocomplete>
);
}
export default LocationSearchInput;
Custom Render Suggestions
This feature allows for custom rendering of autocomplete suggestions. You can style the suggestions and add custom classes based on whether they are active or not.
import React, { useState } from 'react';
import PlacesAutocomplete from 'react-places-autocomplete';
function CustomRenderSuggestions() {
const [address, setAddress] = useState('');
return (
<PlacesAutocomplete
value={address}
onChange={setAddress}
>
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div>
<input {...getInputProps({ placeholder: 'Search Places ...' })} />
<div>
{loading && <div>Loading...</div>}
{suggestions.map(suggestion => {
const className = suggestion.active ? 'suggestion-item--active' : 'suggestion-item';
const style = suggestion.active
? { backgroundColor: '#fafafa', cursor: 'pointer' }
: { backgroundColor: '#ffffff', cursor: 'pointer' };
return (
<div {...getSuggestionItemProps(suggestion, { className, style })}>
<span>{suggestion.description}</span>
</div>
);
})}
</div>
</div>
)}
</PlacesAutocomplete>
);
}
export default CustomRenderSuggestions;
Handling Errors
This feature demonstrates how to handle errors that may occur when fetching autocomplete suggestions from the Google Places API. It logs the error and displays an error message to the user.
import React, { useState } from 'react';
import PlacesAutocomplete from 'react-places-autocomplete';
function HandleErrors() {
const [address, setAddress] = useState('');
const [error, setError] = useState(null);
const handleChange = address => {
setAddress(address);
setError(null);
};
const handleError = (status, clearSuggestions) => {
console.log('Error from Google Maps API', status);
setError(status);
clearSuggestions();
};
return (
<PlacesAutocomplete
value={address}
onChange={handleChange}
onError={handleError}
>
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div>
<input {...getInputProps({ placeholder: 'Search Places ...' })} />
<div>
{loading && <div>Loading...</div>}
{suggestions.map(suggestion => {
const style = suggestion.active
? { backgroundColor: '#a8dadc', cursor: 'pointer' }
: { backgroundColor: '#ffffff', cursor: 'pointer' };
return (
<div {...getSuggestionItemProps(suggestion, { style })}>
{suggestion.description}
</div>
);
})}
</div>
{error && <div className="error">Error: {error}</div>}
</div>
)}
</PlacesAutocomplete>
);
}
export default HandleErrors;
react-google-autocomplete is a React component for Google Places Autocomplete. It provides similar functionality to react-places-autocomplete but is simpler to use with fewer customization options. It is ideal for users who need a straightforward integration without extensive customization.
react-geosuggest is another React component for Google Places Autocomplete. It offers more customization options compared to react-google-autocomplete and includes features like custom suggest rendering and geocoding. It is comparable to react-places-autocomplete in terms of flexibility and customization.
use-places-autocomplete is a React hook for Google Places Autocomplete. It provides a hook-based approach to integrating Google Places Autocomplete into your application. This package is suitable for users who prefer using hooks over components and want more control over the autocomplete logic.
In order to ensure active development going forward, we are looking for maintainers to join the project. Please contact the project owner if you are interested.
A React component to build a customized UI for Google Maps Places Autocomplete
Live demo: hibiken.github.io/react-places-autocomplete/
To install the stable version
npm install --save react-places-autocomplete
React component is exported as a default export
import PlacesAutocomplete from 'react-places-autocomplete';
utility functions are named exports
import {
geocodeByAddress,
geocodeByPlaceId,
getLatLng,
} from 'react-places-autocomplete';
To use this component, you are going to need to load Google Maps JavaScript API
Load the library in your project
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
Create your component
import React from 'react';
import PlacesAutocomplete, {
geocodeByAddress,
getLatLng,
} from 'react-places-autocomplete';
class LocationSearchInput extends React.Component {
constructor(props) {
super(props);
this.state = { address: '' };
}
handleChange = address => {
this.setState({ address });
};
handleSelect = address => {
geocodeByAddress(address)
.then(results => getLatLng(results[0]))
.then(latLng => console.log('Success', latLng))
.catch(error => console.error('Error', error));
};
render() {
return (
<PlacesAutocomplete
value={this.state.address}
onChange={this.handleChange}
onSelect={this.handleSelect}
>
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div>
<input
{...getInputProps({
placeholder: 'Search Places ...',
className: 'location-search-input',
})}
/>
<div className="autocomplete-dropdown-container">
{loading && <div>Loading...</div>}
{suggestions.map(suggestion => {
const className = suggestion.active
? 'suggestion-item--active'
: 'suggestion-item';
// inline style for demonstration purpose
const style = suggestion.active
? { backgroundColor: '#fafafa', cursor: 'pointer' }
: { backgroundColor: '#ffffff', cursor: 'pointer' };
return (
<div
{...getSuggestionItemProps(suggestion, {
className,
style,
})}
>
<span>{suggestion.description}</span>
</div>
);
})}
</div>
</div>
)}
</PlacesAutocomplete>
);
}
}
PlacesAutocomplete is a Controlled Component with a Render Prop. Therefore, you MUST pass at least value
and onChange
callback to the input element, and render function via children
.
Prop | Type | Required | Description |
---|---|---|---|
value | string | :white_check_mark: | value for the input element |
onChange | function | :white_check_mark: | onChange function for the input element |
children | function | :white_check_mark: | Render function to specify the rendering |
onSelect | function | Event handler to handle user's select event | |
onError | function | Error handler function that gets called when Google Maps API responds with an error | |
searchOptions | object | Options to Google Maps API (i.e. bounds, radius) | |
debounce | number | Number of milliseconds to delay before making a call to Google Maps API | |
highlightFirstSuggestion | boolean | If set to true , first list item in the dropdown will be automatically highlighted | |
shouldFetchSuggestions | boolean | Component will hit Google Maps API only if this flag is set true | |
googleCallbackName | string | You can provide a callback name to initialize PlacesAutocomplete after google script is loaded |
Type: string
,
Required: true
Type: function
,
Required: true
Typically this event handler will update value
state.
<PlacesAutocomplete
value={this.state.value}
onChange={value => this.setState({ value })}
>
{/* custom render function */}
</PlacesAutocomplete>
Type: function
Required: true
This is where you render whatever you want to based on the state of PlacesAutocomplete
.
The function will take an object with the following keys.
getInputProps
: functiongetSuggestionItemProps
: functionloading
: booleansuggestions
: arraySimple example
const renderFunc = ({ getInputProps, getSuggestionItemProps, suggestions }) => (
<div className="autocomplete-root">
<input {...getInputProps()} />
<div className="autocomplete-dropdown-container">
{loading && <div>Loading...</div>}
{suggestions.map(suggestion => (
<div {...getSuggestionItemProps(suggestion)}>
<span>{suggestion.description}</span>
</div>
))}
</div>
</div>
);
// In render function
<PlacesAutocomplete value={this.state.value} onChange={this.handleChange}>
{renderFunc}
</PlacesAutocomplete>;
This function will return the props that you can spread over the <input />
element.
You can optionally call the function with an object to pass other props to the input.
// In render function
<input {...getInputProps({ className: 'my-input', autoFocus: true })} />
This function will return the props that you can spread over each suggestion item in your
autocomplete dropdown. You MUST call it with suggestion
object as an argument, and optionally pass an object to pass other props to the element.
// Simple example
<div className="autocomplete-dropdown">
{suggestions.map(suggestion => (
<div {...getSuggestionItemProps(suggestion)}>
{suggestion.description}
</div>
))}
</div>
// Pass options as a second argument
<div className="autocomplete-dropdown">
{suggestions.map(suggestion => {
const className = suggestion.active ? 'suggestion-item--active' : 'suggestion-item';
return (
<div {...getSuggestionItemProps(suggestion, { className })}>
{suggestion.description}
</div>
);
})}
</div>
This is a boolean flag indicating whether or not the request is pending, or has completed.
This is an array of suggestion objects each containing all the data from Google Maps API and other metadata.
An example of a suggestion object.
{
active: false,
description: "San Francisco, CA, USA",
formattedSuggestion: { mainText: "San Francisco", secondaryText: "CA, USA" },
id: "1b9ea3c094d3ac23c9a3afa8cd4d8a41f05de50a",
index: 0,
matchedSubstrings: [ {length: 8, offset: 0} ],
placeId: "ChIJIQBpAG2ahYAR_6128GcTUEo",
terms: [
{ offset: 0, value: "San Francisco" },
{ offset: 15, value: "CA" },
{ offset: 19, value: "USA" }
],
types: ["locality", "political", "geocode"]
}
Type: function
Required: false
,
Default: null
You can pass a function that gets called instead of onChange
function when user
hits the Enter key or clicks on a suggestion item.
The function takes three positional arguments. First argument is address
, second is placeId
and third is the entire suggestion
object.
// NOTE: `placeId` and `suggestion` are null when user hits Enter key with no suggestion item selected.
const handleSelect = (address: string, placeId: ?string, suggestion: ?object) => {
// Do something with address and placeId and suggestion
}
// Pass this function via onSelect prop.
<PlacesAutocomplete
value={this.state.value}
onChange={this.handleChange}
onSelect={this.handleSelect}
>
{/* Custom render function */}
</PlacesAutocomplete>
Type: function
Required: false
You can pass onError
prop to customize the behavior when google.maps.places.PlacesServiceStatus is not OK
(e.g., no predictions are found)
Function takes status
(string) and clearSuggestions
(function) as parameters
// Log error status and clear dropdown when Google Maps API returns an error.
const onError = (status, clearSuggestions) => {
console.log('Google Maps API returned error with status: ', status)
clearSuggestions()
}
<PlacesAutocomplete
value={this.state.value}
onChange={this.handleChange}
onError={onError}
>
{/* Custom render function */}
</PlacesAutocomplete>
Type: Object
Required: false
Default: {}
You can fine-tune the settings passed to the AutocompleteService class with searchOptions
prop.
This prop accepts an object following the same format as google.maps.places.AutocompletionRequest
(except for input
, which comes from the value of the input field).
// these options will bias the autocomplete predictions toward Sydney, Australia with a radius of 2000 meters,
// and limit the results to addresses only
const searchOptions = {
location: new google.maps.LatLng(-34, 151),
radius: 2000,
types: ['address']
}
<PlacesAutocomplete
value={this.state.value}
onChange={this.handleChange}
searchOptions={searchOptions}
>
{/* Custom render function */}
</PlacesAutocomplete>
Type: number
Required: false
Default: 200
The number of milliseconds to delay before making a call to Google Maps API.
Type: boolean
Required: false
Default: false
If set to true
, first suggestion in the dropdown will be automatically set to be active.
Type: boolean
Required: false
Default: true
// Only fetch suggestions when the input text is longer than 3 characters.
<PlacesAutocomplete
value={this.state.address}
onChange={this.handleChange}
shouldFetchSuggestions={this.state.address.length > 3}
>
{/* custom render function */}
</PlacesAutocomplete>
Type: string
Required: false
Default: undefined
If provided, component will initialize after the browser has finished downloading google script.
IMPORTANT: To enable this async mode, you need to provide the same callback name to google script via callback=[YOUR CALLBACK NAME]
.
Example:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=myCallbackFunc"></script>
Then, provide googleCallbackName
prop to PlacesAutocomplete
.
<PlacesAutocomplete
value={this.state.value}
onChange={this.handleChange}
googleCallbackName="myCallbackFunc"
>
{/* custom render function */}
</PlacesAutocomplete>
NOTE: If there are more than one PlacesAutocomplete
components rendered in the page,
set up a callback function that calls a callback function for each component.
Example:
<script>
window.myCallbackFunc = function() {
window.initOne && window.initOne();
window.initTwo && window.initTwo();
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=myCallbackFunc"></script>
<PlacesAutocomplete
value={this.state.value}
onChange={this.handleChange}
googleCallbackName="initOne"
>
{/* custom render function */}
</PlacesAutocomplete>
<PlacesAutocomplete
value={this.state.value}
onChange={this.handleChange}
googleCallbackName="initTwo"
>
{/* custom render function */}
</PlacesAutocomplete>
geocodeByAddress
API/**
* Returns a promise
* @param {String} address
* @return {Promise}
*/
geocodeByAddress(address);
Type: String
,
Required: true
String that gets passed to Google Maps Geocoder
import { geocodeByAddress } from 'react-places-autocomplete';
// `results` is an entire payload from Google API.
geocodeByAddress('Los Angeles, CA')
.then(results => console.log(results))
.catch(error => console.error(error));
geocodeByPlaceId
API/**
* Returns a promise
* @param {String} placeId
* @return {Promise}
*/
geocodeByPlaceId(placeId);
Type: String
,
Required: true
String that gets passed to Google Maps Geocoder
import { geocodeByPlaceId } from 'react-places-autocomplete';
// `results` is an entire payload from Google API.
geocodeByPlaceId('ChIJE9on3F3HwoAR9AhGJW_fL-I')
.then(results => console.log(results))
.catch(error => console.error(error));
getLatLng
API/**
* Returns a promise
* @param {Object} result
* @return {Promise}
*/
getLatLng(result);
Type: Object
Required: true
One of the element from results
(returned from Google Maps Geocoder)
import { geocodeByAddress, getLatLng } from 'react-places-autocomplete';
geocodeByAddress('Tokyo, Japan')
.then(results => getLatLng(results[0]))
.then(({ lat, lng }) =>
console.log('Successfully got latitude and longitude', { lat, lng })
);
Join us on Gitter if you are interested in contributing!
MIT
FAQs
A React component for Google Maps Places Autocomplete
The npm package react-places-autocomplete receives a total of 79,645 weekly downloads. As such, react-places-autocomplete popularity was classified as popular.
We found that react-places-autocomplete demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.