在 React 中使用 Google Place Autocomplete API
2018-10-20
38506
我想在我的 React 组件中有一个自动完成位置搜索栏,但不知道如何实现它。 文档 说要包含
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap" async defer></script>
在 HTML 文件中,然后有一个指向元素的初始化函数 - 我该如何使用我的 React 组件/JSX 来做到这一点?我想我必须导入 api 链接,但我不知道从那里去哪里。
import React from 'react';
import "https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=initMap";
const SearchBar = () => (
<input type="text" id="search"/> //where I want the google autocomplete to be
);
export default SearchBar;
3个回答
通过静态
import
加载 Google Maps API:
import "https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=initMap";
不受支持,您需要为此考虑其他选项:
-
通过 /public/index.html 文件引用 Google Maps API JS 库:
<script src="https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places"></script>
- 或 动态 加载 JS 资源,例如使用 此 库
现在关于
SearchBar
组件,以下示例演示了如何实现简单版本的
Place Autocomplete
(没有基于
此官方示例
import React from "react";
/* global google */
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.autocompleteInput = React.createRef();
this.autocomplete = null;
this.handlePlaceChanged = this.handlePlaceChanged.bind(this);
}
componentDidMount() {
this.autocomplete = new google.maps.places.Autocomplete(this.autocompleteInput.current,
{"types": ["geocode"]});
this.autocomplete.addListener('place_changed', this.handlePlaceChanged);
}
handlePlaceChanged(){
const place = this.autocomplete.getPlace();
this.props.onPlaceLoaded(place);
}
render() {
return (
<input ref={this.autocompleteInput} id="autocomplete" placeholder="Enter your address"
type="text"></input>
);
}
}
,添加了对 Google Map 实例的依赖
Vadim Gremyachev
2018-10-21
这是使用 ES6 + React Hooks 的解决方案:
首先,创建一个
useGoogleMapsApi
钩子来加载外部脚本:
import { useEffect, useState, useCallback } from 'react'
import loadScript from 'load-script'
import each from 'lodash/each'
var googleMapsApi
var loading = false
var callbacks = []
const useGoogleMapsApi = () => {
const [, setApi] = useState()
const callback = useCallback(() => {
setApi(window.google.maps)
}, [])
useEffect(() => {
if (loading) {
callbacks.push(callback)
} else {
if (!googleMapsApi) {
loading = true
loadScript(
`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_MAPS_API_KEY}&libraries=places`,
{ async: true },
() => {
loading = false
googleMapsApi = window.google.maps
setApi(window.google.maps)
each(callbacks, init => init())
callbacks = []
})
}
}
}, [])
return googleMapsApi
}
export default useGoogleMapsApi
然后,这是您的输入组件:
import React, { useRef, useEffect, forwardRef } from 'react'
import useGoogleMapsApi from './useGoogleMapsApi'
const LocationInput = forwardRef((props, ref) => {
const inputRef = useRef()
const autocompleteRef = useRef()
const googleMapsApi = useGoogleMapsApi()
useEffect(() => {
if (googleMapsApi) {
autocompleteRef.current = new googleMapsApi.places.Autocomplete(inputRef.current, { types: ['(cities)'] })
autocompleteRef.current.addListener('place_changed', () => {
const place = autocompleteRef.current.getPlace()
// Do something with the resolved place here (ie store in redux state)
})
}
}, [googleMapsApi])
const handleSubmit = (e) => {
e.preventDefault()
return false
}
return (
<form autoComplete='off' onSubmit={handleSubmit}>
<label htmlFor='location'>Google Maps Location Lookup</label>
<input
name='location'
aria-label='Search locations'
ref={inputRef}
placeholder='placeholder'
autoComplete='off'
/>
</form>
)
}
export default LocationInput
Viola!
Allan of Sydney
2021-07-07
正在为注册表单制作自定义地址自动完成功能,但遇到了一些问题,
// index.html imports the google script via script tag ie: <script src="https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places"></script>
import {useState, useRef, useEffect } from 'React'
function AutoCompleteInput(){
const [predictions, setPredictions] = useState([]);
const [input, setInput] = useState('');
const [selectedPlaceDetail, addSelectedPlaceDetail] = useState({})
const predictionsRef = useRef();
useEffect(
()=>{
try {
autocompleteService.current.getPlacePredictions({ input }, predictions => {
setPredictions(predictions);
});
} catch (err) {
// do something
}
}
}, [input])
const handleAutoCompletePlaceSelected = placeId=>{
if (window.google) {
const PlacesService = new window.google.maps.places.PlacesService(predictionsRef.current);
try {
PlacesService.getDetails(
{
placeId,
fields: ['address_components'],
},
place => addSelectedPlaceDetail(place)
);
} catch (e) {
console.error(e);
}
}
}
return (
<>
<input onChange={(e)=>setInput(e.currentTarget.value)}
<div ref={predictionsRef}
{ predictions.map(prediction => <div onClick={ ()=>handleAutoCompletePlaceSelected(suggestion.place_id)}> prediction.description </div> )
}
</div>
<>
)
}
因此,基本上,您设置了自动完成调用,并在您所在的州取回预测结果。
从那里,使用点击处理程序映射并显示结果,该处理程序将对地点服务执行后续请求,并访问 getDetails 方法以获取完整地址对象或您想要的任何字段。
然后,您将该响应保存到您的本地州,然后就可以开始了。
Denis S Dujota
2020-05-25