У меня есть карта, в нее я передаю чекпоинты, через чилдрен отображаю. Проблема в том, что саму карту обновлять нельзя, потому что переприсваиваются переменные и получаю ошибки, также пробовал полностью переприсвоить компонент карты, получил ошибку связанную с контекстом. При инициализации все ок, но при попытке изменить значения ничего не получаю, стейт меняется, но сам компонент чекпоинта не обновляется. Как сделать так, чтобы он обновился, но не затрагивая при этом компонент карты?
interface MapControllerProps {
getCoords?: ({lng, lat}: {lng: number, lat: number}) => any,
onStyleLoad?: (map: any) => void,
onLoad?: (map: any) => void,
onMouseMove?: (map: any) => void,
waypoints?: Coordinates[]
}
class MapController extends Component<MapControllerProps> {
zoomControl = (map: any) => {
if (map.getZoom() <= 16) {
map.flyTo({
pitch: 0,
bearing: 0
});
} else {
map.flyTo({
pitch: 65,
bearing: 20
});
}
}
shouldComponentUpdate(nextProps) {
if (!this.props.waypoints) {
return false;
}
if (this.props.waypoints.length != nextProps.waypoints.length) {
// Map = ReactMapboxGl({
// accessToken: ENVIRONMENT.mapbox.accessToken
// });
return true;
} else {
return false;
}
return false;
}
render() {
return (
<div id="map-container">
<Map
style="mapbox://styles/mapbox/streets-v8"
containerStyle={{
height: '100%',
width: '100%'
}}
center={[car3DModelLayer.coordinates.lat, car3DModelLayer.coordinates.lng]}
zoom={[17]}
pitch={[65]}
bearing={[20]}
onZoom={this.zoomControl}
onStyleLoad={this.props.onStyleLoad}
onMouseMove={this.props.onMouseMove}
>
<MapContext.Consumer>
{(map: any): any => {
this.props.onLoad ? this.props.onLoad(map) : null;
}}
</MapContext.Consumer>
<ScaleControl position="top-right"/>
<BuildingsLayer3DComponent />
<div>{this.props.children}</div>
</Map>
</div>
);
}
}
interface Coordinates {
lng: number,
lat: number
}
interface MapComponentState {
currentCoordinates?: Coordinates,
checkedCoordinates: Coordinates,
waypoints: Coordinates[]
}
class MapComponent extends Component<{}, MapComponentState> {
state = {
checkedCoordinates: { lng: 0, lat: 0 },
waypoints: [{lat: 24.03862, lng: 49.83498}]
}
getCoords = (coords: {lat: number, lng: number}) => {
console.log("hui")
this.setState({ checkedCoordinates: coords });
}
addWaypoint = () => {
if (this.state.checkedCoordinates.lng == 0 && this.state.checkedCoordinates.lat == 0) {
alert("Enter norm coordinates!");
} else {
this.setState({
waypoints: this.state.waypoints.concat(this.state.checkedCoordinates)
});
}
}
add3DObject(object: Object3DLayer, map: any) {
try {
map.addLayer(object, "waterway-label");
} catch (err) {
console.error(err);
}
}
getRoute() {
axios
.get(`https://api.mapbox.com/directions/v5/mapbox/driving/-122.42,37.78;-77.03,38.91?access_token=${ENVIRONMENT.mapbox.accessToken}`)
.then(({data}) => {
console.log(data);
})
.catch(err => {
console.error(err);
})
}
declareIcon(opts: { path: string, title: string}, map: any) {
map.loadImage(opts.path, (err, image) => {
if (err) {
console.error(err);
} else {
try {
map.addImage(opts.title, image);
} catch (err) {
console.error(err);
}
}
});
}
handleMapClick(map: any) {
map.on('mousedown', (e: any) => {
try {
this.setState({ checkedCoordinates: e.lngLat.wrap() });
} catch (err) {
console.error(err);
}
});
}
componentDidUpdate() {
console.log(this.state.waypoints);
}
handleMapLoad = (map: any) => {
this.declareIcon({path: '/img/map-marker-icon.png', title: 'map-marker-icon'}, map);
this.handleMapClick(map);
}
handleMapStyleClick = (map: any) => {
try {
this.add3DObject(car3DModelLayer, map);
} catch (err) {
console.error(err);
}
}
render() {
return(
<div>
<MapController waypoints={this.state.waypoints} onStyleLoad={this.handleMapStyleClick} onLoad={this.handleMapLoad} getCoords={this.getCoords}>
<Checkpoint textColor="#ffffff" icon="map-marker-icon" iconScale={0.15} points={this.state.waypoints} />
</MapController>
<RoutingForm handleClick={this.addWaypoint} lat={this.state.checkedCoordinates.lat} lng={this.state.checkedCoordinates.lng} />
</div>
);
}
}