React-google-maps 用户位置
Posted
技术标签:
【中文标题】React-google-maps 用户位置【英文标题】:React-google-maps user location 【发布时间】:2020-04-07 09:42:21 【问题描述】:试图在我的反应应用程序中设置一个谷歌地图,该地图以用户位置为中心并返回地址。有人能告诉我如何编辑以下代码,以便地图和标记加载到用户位置。我知道如何设置地理位置,但似乎无法在不破坏现有代码的情况下做到这一点
地图组件
import React, Component from 'react';
import withGoogleMap, GoogleMap, withScriptjs, InfoWindow, Marker from "react-google-maps";
import Geocode from "react-geocode";
import Autocomplete from 'react-google-autocomplete';
Geocode.setApiKey( "googleAPIkey" );
Geocode.enableDebug();
class Map extends Component
constructor( props )
super( props );
this.state =
address: '',
city: '',
area: '',
state: '',
mapPosition:
lat: this.props.center.lat,
lng: this.props.center.lng
,
markerPosition:
lat: this.props.center.lat,
lng: this.props.center.lng
/**
* Get the current address from the default map position and set those values in the state
*/
componentDidMount()
Geocode.fromLatLng( this.state.mapPosition.lat , this.state.mapPosition.lng ).then(
response =>
const address = response.results[0].formatted_address,
addressArray = response.results[0].address_components,
city = this.getCity( addressArray ),
area = this.getArea( addressArray ),
state = this.getState( addressArray );
console.log( 'city', city, area, state );
this.setState(
address: ( address ) ? address : '',
area: ( area ) ? area : '',
city: ( city ) ? city : '',
state: ( state ) ? state : '',
)
,
error =>
console.error( error );
);
;
/**
* Component should only update ( meaning re-render ), when the user selects the address, or drags the pin
*
* @param nextProps
* @param nextState
* @return boolean
*/
shouldComponentUpdate( nextProps, nextState )
if (
this.state.markerPosition.lat !== this.props.center.lat ||
this.state.address !== nextState.address ||
this.state.city !== nextState.city ||
this.state.area !== nextState.area ||
this.state.state !== nextState.state
)
return true
else if ( this.props.center.lat === nextProps.center.lat )
return false
/**
* Get the city and set the city input value to the one selected
*
* @param addressArray
* @return string
*/
getCity = ( addressArray ) =>
let city = '';
for( let i = 0; i < addressArray.length; i++ )
if ( addressArray[ i ].types[0] && 'administrative_area_level_2' === addressArray[ i ].types[0] )
city = addressArray[ i ].long_name;
return city;
;
/**
* Get the area and set the area input value to the one selected
*
* @param addressArray
* @return string
*/
getArea = ( addressArray ) =>
let area = '';
for( let i = 0; i < addressArray.length; i++ )
if ( addressArray[ i ].types[0] )
for ( let j = 0; j < addressArray[ i ].types.length; j++ )
if ( 'sublocality_level_1' === addressArray[ i ].types[j] || 'locality' === addressArray[ i ].types[j] )
area = addressArray[ i ].long_name;
return area;
;
/**
* Get the address and set the address input value to the one selected
*
* @param addressArray
* @return string
*/
getState = ( addressArray ) =>
let state = '';
for( let i = 0; i < addressArray.length; i++ )
for( let i = 0; i < addressArray.length; i++ )
if ( addressArray[ i ].types[0] && 'administrative_area_level_1' === addressArray[ i ].types[0] )
state = addressArray[ i ].long_name;
return state;
;
/**
* And function for city,state and address input
* @param event
*/
onChange = ( event ) =>
this.setState( [event.target.name]: event.target.value );
;
/**
* This Event triggers when the marker window is closed
*
* @param event
*/
onInfoWindowClose = ( event ) =>
;
/**
* When the marker is dragged you get the lat and long using the functions available from event object.
* Use geocode to get the address, city, area and state from the lat and lng positions.
* And then set those values in the state.
*
* @param event
*/
onMarkerDragEnd = ( event ) =>
let newLat = event.latLng.lat(),
newLng = event.latLng.lng();
Geocode.fromLatLng( newLat , newLng ).then(
response =>
const address = response.results[0].formatted_address,
addressArray = response.results[0].address_components,
city = this.getCity( addressArray ),
area = this.getArea( addressArray ),
state = this.getState( addressArray );
this.setState(
address: ( address ) ? address : '',
area: ( area ) ? area : '',
city: ( city ) ? city : '',
state: ( state ) ? state : '',
markerPosition:
lat: newLat,
lng: newLng
,
mapPosition:
lat: newLat,
lng: newLng
,
)
,
error =>
console.error(error);
);
;
/**
* When the user types an address in the search box
* @param place
*/
onPlaceSelected = ( place ) =>
console.log( 'plc', place );
const address = place.formatted_address,
addressArray = place.address_components,
city = this.getCity( addressArray ),
area = this.getArea( addressArray ),
state = this.getState( addressArray ),
latValue = place.geometry.location.lat(),
lngValue = place.geometry.location.lng();
// Set these values in the state.
this.setState(
address: ( address ) ? address : '',
area: ( area ) ? area : '',
city: ( city ) ? city : '',
state: ( state ) ? state : '',
markerPosition:
lat: latValue,
lng: lngValue
,
mapPosition:
lat: latValue,
lng: lngValue
,
)
;
render()
const AsyncMap = withScriptjs(
withGoogleMap(
props => (
<GoogleMap google= this.props.google
defaultZoom= this.props.zoom
defaultCenter= lat: this.state.mapPosition.lat, lng: this.state.mapPosition.lng
>
/* InfoWindow on top of marker */
<InfoWindow
onClose=this.onInfoWindowClose
position= lat: ( this.state.markerPosition.lat + 0.0018 ), lng: this.state.markerPosition.lng
>
<div>
<span style= padding: 0, margin: 0 > this.state.address </span>
</div>
</InfoWindow>
/*Marker*/
<Marker google=this.props.google
name='Dolores park'
draggable=true
onDragEnd= this.onMarkerDragEnd
position= lat: this.state.markerPosition.lat, lng: this.state.markerPosition.lng
/>
<Marker />
/* For Auto complete Search Box */
</GoogleMap>
)
)
);
let map;
if( this.props.center.lat !== undefined )
map = <div>
<div>
<div className="form-group">
<label htmlFor="">City</label>
<input type="text" name="city" className="form-control" onChange= this.onChange readOnly="readOnly" value= this.state.city />
</div>
<div className="form-group">
<label htmlFor="">Area</label>
<input type="text" name="area" className="form-control" onChange= this.onChange readOnly="readOnly" value= this.state.area />
</div>
<div className="form-group">
<label htmlFor="">State</label>
<input type="text" name="state" className="form-control" onChange= this.onChange readOnly="readOnly" value= this.state.state />
</div>
<div className="form-group">
<label htmlFor="">Address</label>
<input type="text" name="address" className="form-control" onChange= this.onChange readOnly="readOnly" value= this.state.address />
</div>
</div>
<AsyncMap
googleMapURL="https://maps.googleapis.com/maps/api/js?key=googleAPIke"
loadingElement=
<div style= height: `100%` />
containerElement=
<div style= height: this.props.height />
mapElement=
<div style= height: `100%` />
/>
</div>
else
map = <div style=height: this.props.height />
return( map )
export default Map
index.js 页面
import React, Component from 'react';
import Map from '../components/Map';
class Index extends Component
render()
return(
<div style= margin: '100px' >
<Map
google=this.props.google
center=lat: 18.5204, lng: 73.8567
height='300px'
zoom=15
/>
</div>
);
export default Index;```
【问题讨论】:
【参考方案1】:..好吧,我想通了。可能不是最好的方法。但它有效。
import React, Component from 'react';
import Map from '../components/Map';
import CreateJob from '../components/CreateJob';
class Index extends Component
state = userLocation: lat: 32, lng: 32 , loading: true ;
componentDidMount(props)
navigator.geolocation.getCurrentPosition(
position =>
const latitude, longitude = position.coords;
this.setState(
userLocation: lat: latitude, lng: longitude ,
loading: false
);
,
() =>
this.setState( loading: false );
);
render()
const loading, userLocation = this.state;
const google = this.props;
if (loading)
return null;
return(
<div style=
margin: '0px',
>
<Map
google=this.props.google
center=userLocation
height='350px'
zoom=18
/>
<CreateJob />
</div>
);
export default Index;
【讨论】:
以上是关于React-google-maps 用户位置的主要内容,如果未能解决你的问题,请参考以下文章
React-Google-Maps 显示两个标记,一个在原始位置,另一个标记跟随地图的新中心 onDrag
当用户点击 react-google-maps 中的地图或标记时执行操作