@cester

Разбить react компонент на контейнер и компонент?

Добрый день! Помогите пожалуйста разбить гугл мапс компонент на контейнер и компонент.
В проекте использую 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)


Спасибо!
  • Вопрос задан
  • 359 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
24 нояб. 2024, в 03:11
500 руб./за проект
24 нояб. 2024, в 01:35
5000 руб./за проект
24 нояб. 2024, в 01:24
500 руб./за проект