Добрый день! Помогите пожалуйста разбить гугл мапс компонент на контейнер и компонент.
В проекте использую redux, но в ходе работы над данным компонентом писал все в одном файле и получилось много кода.
Не совсем понимаю как сейчас лучше оптимизировать это все.
В компонент сейчас приходят основные данные с redux и отдельно есть еще свой стейт. Не знаю на сколько это правильно в redux.
Буду благодарен за советы как лучше работать в таких случаях, как правильно построить структуру приложения.
Сам компонент
import React from 'react';
import GoogleMapReact from 'google-map-react';
import supercluster from 'points-cluster';
import Marker from '../Marker/index';
import MarkerSm from '../Marker/MarkerSm';
import ClusterMarker from '../ClusterMarker/index';
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import {bootstrapURLKeys} from '../bootstrapURLKeys';
import {susolvkaCoords} from '../fakeData';
import {cutMarkers} from 'helpers/cutMarkers';
import RaisedButton from 'material-ui/RaisedButton';
import {
selectCompany,
changeMap,
intervalData,
zoomCluster,
handleMapChange,
clusterChange,
polyLineModeActivate,
loadedPolylineMarkers,
loadedFakePolyline
} from 'actions'
import Polyline from '../Directions/PolyLine';
import info from './routes-j.json';
const MAP = {
defaultZoom: 7,
defaultCenter: susolvkaCoords,
options: {
// styles: mapStyles,
maxZoom: 30,
},
};
/*let arr2 = info.info.map(item => {
return {lat: +item.lat, lng: +item.lng}
});
let arr3 = [];
/!*for (let i = 0; i < 80000; i++) {
arr3.push({lat: arr2[arr2.length - 1].lat + (i / 10000), lng: arr2[arr2.length - 1].lng + (i / 10000)})
}*!/
arr2 = [...arr2, ...arr3];*/
class GoogleMap extends React.PureComponent {
state = {
mapOptions: {
center: susolvkaCoords,
zoom: MAP.defaultZoom,
},
clusters: [],
apiLoaded: false,
polyLinePath: [],
loadChart: false
};
getClusters = () => {
const clusters = supercluster(this.props.selectedCompany.carList, {
minZoom: 0,
maxZoom: 36,
radius: 200
});
return clusters(this.state.mapOptions);
};
createClusters = props => {
if(this.props.selectedCompany.mapMode !== 'routes_mode') {
this.setState({
clusters: this.state.mapOptions.bounds
? this.getClusters(props).map(({wx, wy, numPoints, points}) => ({
lat: wy,
lng: wx,
numPoints,
id: `${numPoints}_${points[0].id}`,
points
}))
: []
});
}
};
handleMapChange = ({center, zoom, bounds}) => {
if(this.props.selectedCompany.mapMode !== 'routes_mode') {
this.setState({
mapOptions: {
center,
zoom,
bounds
},
},
() => {
this.createClusters(this.props);
}
);
this.props.handleMapChange({center, zoom, bounds})
} else {
this.setState({
mapOptions: {
center,
zoom,
bounds
},
});
let cutMark = cutMarkers(this.state.map, this.props.selectedCompany.polyLinePath, 100);
this.props.loadPolylineMarkers(cutMark)
}
};
componentDidMount() {
let {lat, lng} = this.props.selectedCompany.carList[0];
this.setState({
mapOptions: {
center: {lat: +lat, lng: +lng}
}
});
this.timerID = setInterval(
() => this.tick(),
5000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
if(this.props.selectedCompany.mapMode === 'routes_mode') {
let arr2 = this.props.selectedCompany.polyLinePath;
let arr3 = [];
/*for (let i = 0; i < 20; i++) {
arr3.push({
lat: arr2[arr2.length - 1].lat + (i / 300),
lng: arr2[arr2.length - 1].lng - (i / 300),
id: Date.now() + i,
car_name: Date.now()
})
}
let cutMark = cutMarkers(this.state.map, this.props.selectedCompany.polyLinePath, 100);
this.props.loadFakePolyline(arr3, cutMark)*/
// this.setState({
// polyLinePath: [...this.state.polyLinePath, ...arr3]
/*
*/
// });
}
}
onUpdate = (pos) => {
this.setState({
mapOptions: {
zoom: this.state.mapOptions.zoom + 1,
center: pos
},
});
this.props.zoomCluster(pos)
// console.log(this.props.changeMap.mapOptions)
};
apiLoaded = (map, maps) => {
this.setState({
map: map,
mapApi: maps,
// apiLoaded: true
})
};
drawRoute = () => {
let arr2 = info.info.map(item => {
return {lat: +item.lat, lng: +item.lng, id: item.id, car_name: item.car_name}
});
let arr3 = [];
arr2 = [...arr2, ...arr3];
let cutMark = cutMarkers(this.state.map, info.info, 80);
this.props.polylineMode(arr2, cutMark);
let {lat, lng} = arr2[0];
this.setState({
apiLoaded: true,
// polyLinePath: arr2,
mapOptions: {
center: {lat: +lat, lng: +lng}
}
});
};
loadChart = () => {
this.setState({
loadChart: !this.state.loadChart
})
};
render() {
return (
<div style={{width: `100%`, height: `100%`, position: `relative`}}>
<RaisedButton label="Load Route" primary={true} onClick={this.drawRoute}
style={{left: '460px', top: '15px', position: 'absolute', zIndex: '99'}}/>
<RaisedButton label="Load Chart" primary={true} onClick={this.loadChart}
style={{left: '660px', top: '15px', position: 'absolute', zIndex: '99'}}/>
{/*<button type="button" onClick={this.drawRoute}>button</button>*/}
<GoogleMapReact
zoom={this.state.mapOptions.zoom}
defaultCenter={MAP.defaultCenter}
center={this.state.mapOptions.center}
options={MAP.options}
onChange={this.handleMapChange}
yesIWantToUseGoogleMapApiInternals
bootstrapURLKeys={bootstrapURLKeys}
onGoogleApiLoaded={({map, maps}) => this.apiLoaded(map, maps)}
>
{this.state.apiLoaded ?
<Polyline map={this.state.map} mapApi={this.state.mapApi} draggable={true}
onMouseOver={this.hoverLine} options={{
strokeColor: '#992a49',
strokeOpacity: 0.9,
strokeWeight: 3
}} path={this.props.selectedCompany.polyLinePath}/> : null}
{this.props.selectedCompany.mapMode !== 'routes_mode' ?
this.state.clusters.map((item, i, arr) => {
if(item.numPoints === 1) {
return (
<Marker
key={item.id}
lat={item.points[0].lat}
lng={item.points[0].lng}
name={item.points[0].car_name}
/>
);
}
return (
<ClusterMarker
key={item.id}
lat={item.lat}
lng={item.lng}
points={item.points}
onUpdate={this.onUpdate}
mode={this.props.selectedCompany.mapMode}
/>
);
}) :
this.props.selectedCompany.carList.map((item, i, arr) => {
let parking;
if(typeof arr[i - 1] !== 'undefined') {
if(arr[i - 1].lng === arr[i].lng) {
parking = true;
} else {
parking = false;
}
}
return (
<MarkerSm
key={item.id}
lat={item.lat}
lng={item.lng}
parking={parking}
// name={item.points[0].car_name}
/>
);
})
}
</GoogleMapReact>
{/*{this.state.loadChart ?*/}
{/*<CustomChart data={allData} maxPoints={120}/>*/}
{/*: null}*/}
</div>
);
}
}
const mapStateToProps = (state) => {
return {
selectedCompany: state.selectedCompanyReducer,
// changedMap: state.mainMapReducer,
// intervalData: state.intervalDataReducer,
changeMap: state.mainMapReducer
}
};
const mapDispatchToProps = (dispatch) => {
return {
// changeMap: bindActionCreators(changeMap, dispatch),
// intervalData: bindActionCreators(intervalData, dispatch),
zoomCluster: bindActionCreators(zoomCluster, dispatch),
handleMapChange: bindActionCreators(handleMapChange, dispatch),
clusterChange: bindActionCreators(clusterChange, dispatch),
polylineMode: bindActionCreators(polyLineModeActivate, dispatch),
loadPolylineMarkers: bindActionCreators(loadedPolylineMarkers, dispatch),
loadFakePolyline: bindActionCreators(loadedFakePolyline, dispatch)
}
};
export default connect(mapStateToProps, mapDispatchToProps)(GoogleMap)
Спасибо!