Перво-наперво, измените имя компонента map
на Map
. Прочитайте на этом посте .
Теперь относительно этого:
когда я использую постоянные числа в месте отправления и назначения, все работает нормально.
Ответ на этот вопрос имеет подоплеку, продолжайте читать, чтобы он был более понятным.
Проблема контекста 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
.
Это код приведенного вами примера :
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
равно MapWithADirectionsRenderer
.
Теперь в своем коде вы создаете новый компонент с именем MyMapComponent
в качестве объекта const. Этот компонент позволяет вам определить функцию componentDidMount
этого нового компонента. Этот новый компонент будет иметь собственный контекст, поэтому, когда вы пишете this
внутри компонента MyMapComponent
, он будет ссылаться на MyMapComponent
, а не на map
.
Вы не можете получить доступ к состоянию map
изнутри MyMapComponent
таким образом, вы должны передать реквизиты MyMapComponent
.
Решение
Я создал несколько примеров того, как передавать значения.
Решение 1
Вы можете создать реквизит с любым именем (в данном примере это называется 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>
));
Таким образом, вы можете регистрировать this.props.test
с заданным значением, что бы вы ни использовали.
Решение 2
Если вам нужно визуализировать компонент в зависимости от значения, найденного в состоянии 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} />
Это полный компонент:
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%` }} />,
}),
withScriptjs,
withGoogleMap,
)(props => (
<GoogleMap defaultZoom={8} defaultCenter={{ lat: -34.397, lng: 150.644 }}>
{props.isMarkerShown && (
<Marker position={{ lat: props.latProp, lng: props.lngProp }} />
)}
</GoogleMap>
));
class App extends Component{
constructor(props){
super(props);
this.state = { lat: -34.400, lng: 151.644 }
}
render(){
return (
<div>
<MyMapComponent isMarkerShown latProp={this.state.lat} lngProp={this.state.lng} />
</div>
);
}
}
export default App;