我正在使用库react-google-maps,并且我想在两个节点之间使用DirectionsRenderer。 这是我的状态
this.state={
currentPosition:{lat: 26.84 ,lng: 75.80},
destinationPosition:{lat: 26.84 ,lng: 75.80},
};
我想显示当前位置和标记之间的方向。我的componentDidMount()在render方法中。 这是渲染方法的代码
class map extends React.PureComponent{
constructor(props){
super(props);
this.state={
currentPosition:{lat: 26.84 ,lng: 75.80},
destinationPosition:{lat: 26.84 ,lng: 75.80},
direction:false
};
}
onMarkerPositionChanged(e){
this.setState((state)=>({
destinationPosition:{lat:e.latLng.lat(),lng:e.latLng.lng()}}));
}
handleClick(){
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition((position)=>{
this.setState(()=>({
currentPosition:{lat:position.coords.latitude,lng:position.coords.longitude}}))
});
}
else{
alert("Geoloaction is not supported by your browser");
}
}
changeDir(){
if(this.state.direction)
this.setState(()=>({direction:false}))
else
this.setState(()=>({direction:true}))
}
render(){
const MyMapComponent = compose(
withProps({
googleMapURL: "https://maps.googleapis.com/maps/api/js?key=AIzaSyC5VMMlyr_A6K5ycpOrq3OsVM8YYbn0q3A&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `300px` }} />,
mapElement: <div style={{ height: `100%` }} />,
}),
withScriptjs,
withGoogleMap,
lifecycle({
componentDidMount() {
const google=window.google;
console.log(this.state);
//--->this statement prints null
const DirectionsService = new google.maps.DirectionsService();
DirectionsService.route({
origin: new google.maps.LatLng(this.state.currentPosition.lat, this.state.currentPosition.lng),
destination: new google.maps.LatLng(this.state.destinationPosition.lat,this.state.destinationPosition.lng),
//----> this is where i want to use the state to get the direction between //current location and marker
travelMode: google.maps.TravelMode.DRIVING,
}, (result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
this.setState({
directions: result,
});
} else {
console.error(`error fetching directions ${result}`);
}
});
}
})
)(
props =>
<GoogleMap defaultZoom={15} defaultCenter={this.state.destinationPosition} >
<Marker position={this.state.destinationPosition} draggable changeLat
onDragEnd={this.onMarkerPositionChanged.bind(this)}
/>
<Marker
icon="https://www.robotwoods.com/dev/misc/bluecircle.png"
position={this.state.currentPosition}
/>
{this.state.direction && props.directions && <DirectionsRenderer directions={props.directions} />}
<Button bsStyle="success" onClick={this.handleClick.bind(this)}>Current Position</Button>
<Button bsStyle="success" onClick={this.changeDir.bind(this)}>Get Direction</Button>
</GoogleMap>
);
return(
<Container state={this.state} map={MyMapComponent}/>
);
}
}
export default map;
当我使用常数代替起点和终点时,效果很好。
答案 0 :(得分:0)
首先,将组件map
的名称更改为Map
。阅读at this SO post。
现在,关于这一点:
当我使用常数代替起点和终点时,效果很好。
该问题的答案有一定的背景,请继续阅读以下内容,以使内容更加清楚。
this
上下文问题
在代码中,您有一个map
组件,您可以使用this
访问其任何属性(包括状态)。例如,如果您在this.state
函数内调用render
,则会得到map
的状态。您可以使用componentDidMount
组件的map
函数,例如,在状态中设置一个值,如下所示:
class map extends Component {
constructor(props){
this.state = { myVal: 1}
}
componentDidMount(){
this.setState({ myVal: 2})
}
}
该代码不会失败,因为componentDidMount是该组件的React函数,并且this
可以在组件内部使用,因为它处于同一上下文中。在这种情况下,this.setState
将设置map
的状态,因为this
是map
。
这是the example you provided的代码:
const { compose, withProps, lifecycle } = require("recompose"); const { withScriptjs, withGoogleMap, GoogleMap, DirectionsRenderer, } = require("react-google-maps");
const MapWithADirectionsRenderer = compose( withProps({
googleMapURL: "https://maps.googleapis.com/maps/api/js?key=AIzaSyC4R6AN7SmujjPUIGKdyao2Kqitzr1kiRg&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />, }), withScriptjs, withGoogleMap, lifecycle({
componentDidMount() {
const DirectionsService = new google.maps.DirectionsService();
DirectionsService.route({
origin: new google.maps.LatLng(41.8507300, -87.6512600),
destination: new google.maps.LatLng(41.8525800, -87.6514100),
travelMode: google.maps.TravelMode.DRIVING,
}, (result, status) => {
if (status === google.maps.DirectionsStatus.OK) {
this.setState({
directions: result,
});
} else {
console.error(`error fetching directions ${result}`);
}
});
} }) )(props => <GoogleMap
defaultZoom={7}
defaultCenter={new google.maps.LatLng(41.8507300, -87.6512600)}
>
{props.directions && <DirectionsRenderer directions={props.directions} />} </GoogleMap> );
<MapWithADirectionsRenderer />
在此示例中,this.setState
指的是MapWithADirectionsRenderer
的上下文,因此this.setState
设置MapWithADirectionsRenderer
的状态,因为this
是{{1 }}。
现在,在您的代码中,您将创建一个名为MapWithADirectionsRenderer
的新组件作为const对象。该组件使您可以定义该新组件的MyMapComponent
函数。该新组件将具有自己的上下文,因此,当您在componentDidMount
组件内编写this
时,它将引用MyMapComponent
,而不是MyMapComponent
。
您无法像这样从map
内部访问map
的状态,必须将道具传递给MyMapComponent
。
我创建了一些有关如何传递值的示例。
解决方案1
您可以创建任何名称的道具(在本示例中,其值为MyMapComponent
,称为test):
My value
通过这种方式,无论使用什么,都可以使用给定值记录const MyMapComponent = compose(
withProps({
googleMapURL:
"https://maps.googleapis.com/maps/api/js?key=AIzaSyC5VMMlyr_A6K5ycpOrq3OsVM8YYbn0q3A&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />,
test:'My value'
}),
lifecycle({
componentDidMount() {
console.log(JSON.stringify(this.props.test));
}
}),
withScriptjs,
withGoogleMap,
)(props => (
<GoogleMap defaultZoom={8} defaultCenter={{ lat: -34.397, lng: 150.644 }}>
{props.isMarkerShown && (
<Marker position={{ lat: -34.397, lng: 150.644 }} />
)}
</GoogleMap>
));
。
解决方案2
如果您需要根据在this.props.test
状态下找到的值来渲染组件,请使用类似的东西。
您可以将道具传递到Map
,然后使用MyMapComponent
并添加道具名称来访问它们。
例如,如果您通过一个名为props.
的新道具,如下所示:
latProp
您可以这样访问它:
<MyMapComponent isMarkerShown latProp={-34.397} />
由于您要用状态中的常量替换常数值,所以只需用状态中的任何属性替换(props => (
<GoogleMap defaultZoom={8} defaultCenter={{ lat: -34.397, lng: 150.644 }}>
{props.isMarkerShown && (
<Marker position={{ lat: props.latProp, lng: 150.644 }} />
)}
</GoogleMap>
));
中发送的值:
props.latProp
这是完整的组件:
<MyMapComponent isMarkerShown latProp={this.state.lat} />