我想在我的react组件中有一个自动完成位置搜索栏,但是不知道如何实现它。 documentation说要包含
<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;
答案 0 :(得分:5)
通过静态import
加载Google Maps API:
import "https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=initMap";
不受支持,为此您需要考虑其他选项:
<script src="https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places"></script>
现在有关SearchBar
组件,以下示例演示了如何基于this official example实现 Place Autocomplete 的简单版本(不依赖于Google Map实例)>
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>
);
}
}
答案 1 :(得分:0)
使注册表格的自定义地址自动完成并遇到了一些问题,
// 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>
<>
)
}
因此,基本上,您可以设置自动完成呼叫,并以本地状态获取预测结果。
从此处映射并显示带有单击处理程序的结果,该处理程序将对places服务发出后续请求,并可以访问完整地址对象或所需的任何字段的getDetails方法。
然后将响应保存到本地状态,然后退出。
答案 2 :(得分:0)
这是一个使用 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
中提琴!