Если я правильно понимаю, вы хотите отображать ответ, поступающий от API-адресов Mapbox, всякий раз, когда обновляется props.itineraryReducer
, и который вы храните в state.data
. Следовательно, вы можете использовать ComponentDidUpdate
- метод жизненного цикла React, который вы можете использовать для воздействия на изменения в вашем компоненте (будь то состояние или подпорки) - чтобы инициировать обновление на вашей карте всякий раз, когда эти подпорки и переменные состояния изменяются. Вы можете сделать что-то вроде этого:
componentDidMount (prevProps, prevState) {
const { data } = this.state
const { itineraryReducer } = this.props
if (prevProps.itineraryReducer !== itineraryReducer) {
if (itineraryReducer.itinerary.length > 1) {
const url =
'https://api.mapbox.com/directions/v5/mapbox/' +
'driving/' +
this.getItineraryCoords() +
'?geometries=geojson&' +
'access_token='...';
fetch(url)
.then(response => response.json())
.then(
result => {
result.routes
? this.setState({
data: result.routes[0].geometry.coordinates,
isLoaded: true,
})
: this.setState({
isLoaded: true,
});
},
error => { // You should probably catch this error on a .catch() in your promise chain
this.setState({
isLoaded: true,
error: error,
});
}
);
}
}
if (prevState.data !== data) {
this.addLineLayer(data) // Here is where we are actually drawing the line map layer
}
}
addLineLayer = (coords) => {
this.map.addLayer({
id: 'route',
type: 'line',
source: {
type: 'geojson',
data: {
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: this.state.data,
},
},
},
layout: {
'line-join': 'round',
'line-cap': 'round',
},
paint: {
'line-color': '#888',
'line-width': 8,
},
});
this.map.resize();
}
// ... (Rest of the Component)
Потенциально, в зависимости от вашей цели, вам придется удалить предыдущий существующий слой на карте, прежде чем рисовать следующий слой. Вы можете проверить эту ссылку для ссылки на вызываемый метод.
Возможно, вы также заметили, что к объекту карты обращаются в this.map
, поэтому вам нужно сохранить map
объект в вашем экземпляре класса при загрузке стиля. Для этого вы можете передать следующий метод в качестве атрибута onStyleLoad
в <Map>
:
onStyleLoad = (map) => {
this.map = map // This saves the object map in your class instance, so that you can access it later
}
...
<Map
style="mapbox://styles/mapbox/streets-v8"
className="mapContainer"
center={this.state.data[0]}
zoom={this.state.zoom}
onStyleLoad={this.onStyleLoad}
>
...