how to pass the data from one Component to another component - reactjs

I have created two components. one is for the map and other one is for some inputs. I have two inputs to get the latitude and longitude. I am passing the longitude and latitude which i got from the user, to my other component using longitude= {this.state.longitude} latitude = {this.state.latitude}. If user haven't input the longitude and latitude or user clear the input it should show these coordinates lat: 22.5726, lng: 88.3639. how can i do it ? so far this is what i have done. when i pass the coordinates it doesn't show the place.what have i done wrong? And also i want to know how i can show the default coordinates when user clear the input? when i console.log this.props.latitude i get following error TypeError: Cannot read property 'latitude' of undefined. I think My data is not passing Properly to my map Component !if anyone knows how to fix this please tell!
this is my file structure.
MainFolder
|
|__ navigation.js
|
|__ right folder
| |
| |__form.js(this is where i have two inputs)
| |
| |__ MapContainerFolder
| |
| |__MapContainer.js
|
|
|__ left folder
|
|__left.js
In my Form component i have below code
<MapContainer
longitude= {this.state.longitude}
latitude = {this.state.latitude}
/>
in my navigation.js i have this
<form/>
<left/>
this is my mapContainer.js
import React, { Component } from "react";
import {Map, InfoWindow, Marker, GoogleApiWrapper} from 'google-maps-react';
export class MapContainer extends Component {
render() {
const style = {
width: '24%',
height: '65%'
}
return (
<Map
style={style}
google={this.props.google}
zoom={14}
initialCenter={{
lat: 22.5726,
lng: 88.3639
}}
center={{
lat:this.props.longitude,
lng:this.props.latitude
}}
>
<Marker onClick={this.onMarkerClick}
name={'Current location'} />
<InfoWindow onClose={this.onInfoWindowClose}>
<div>
</div>
</InfoWindow>
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: ("my api key")
})(MapContainer)

In your MapcContainer class, you need to define your initail state based on the props you pass to this component from outside and set a default for them. Since I don't have a Google API key, I'm going to demonstrate your example in Leaflet, but I'm sure you'll get the idea.
const { Map: LeafletMap, TileLayer, Marker, Popup } = window.ReactLeaflet
class App extends React.Component {
constructor(props) {
super(props);
const lat = this.props.latitude || 51.505;
const lng = this.props.longitude || -0.091;
this.state = {
center: [lat,lng],
zoom: 13
};
}
render() {
return (
<div>
<LeafletMap center={this.state.center} zoom={this.state.zoom}>
<TileLayer
attribution='&copy OpenStreetMap contributors'
url="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
/>
<Marker position={this.state.center}>
<Popup>Hello World!
</Popup>
</Marker>
</Map>
</div>
);
}
}
const rootElement = document.getElementById("root");
const Wrapper = () => <App latitude={51.505} longitude={-0.091} />;
ReactDOM.render(<Wrapper />, rootElement);

Related

How to use "Cloud-based maps styling" in lib "#react-google-maps/api"

I have a React code with . I created in console.cloud "Map styles" and mapId and linked them. Then I added the mapId to the code, but the styles didn't change.
render() {
return (
<LoadScript
mapIds={["xxxxxxxxxxxxx"]}
// id="6e120bcd575d29f7"
googleMapsApiKey="xxxxxxxxxxxxxxxxxxx"
>
<GoogleMap
mapContainerStyle={containerStyle}
center={{
lat: 50.751642333131244,
lng: 25.329876895818945
}}
zoom={17}
>
<Marker
onLoad={this.onLoad}
position={{
lat: 50.7516779698738,
lng: 25.329030658899786
}}
/>
</GoogleMap>
</LoadScript>
)
}
}
To implement Cloud-based maps styling, you need to add the mapId in the Maps Javascript script tag's &map_ids= parameter and the map object mapId parameter. The code you have only adds the mapId in the Maps JavaScript script tag. To add the mapId in your map object parameter, you need to add the mapId option inside your object to implement this styling using the #react-google-maps/api library. See working sample code and code snippet below:
import ReactDOM from "react-dom";
import React from "react";
import {
GoogleMap,
LoadScript
} from "#react-google-maps/api";
const lib = ["places"];
const id = ["6e120bcd575d29f7"]
const key = ""; // PUT GMAP API KEY HERE
const defaultLocation = { lat: 40.756795, lng: -73.954298 };
class Map extends React.Component {
render() {
return (
<div>
<LoadScript googleMapsApiKey={key} libraries={lib} mapIds={id} >
<GoogleMap
center={defaultLocation}
zoom={5}
options={{ mapId: "6e120bcd575d29f7" }}
mapContainerStyle={{ height: "400px", width: "800px" }}
/>
</LoadScript>
</div>
);
}
}
I removed mapId then styles worked.

Is this the correct usage of React Components?

I am new to React. I want to share my components files with you. The code is syntactically correct and executes just fine. I just want to know, if its logically correct and the correct use of concepts such as states.
Is it correct to save lng and lat coords from the GeoLocation API to the MapContainer State?
Is it the correct use of ComponentDidMount() function.
What other ways can I improve the code.
// Map.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css';
import GoogleMapReact from 'google-map-react';
function Map(props) {
const screenHeight = window.screen.height;
return (
<div style={{ height: screenHeight - 250 }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "123mykey" }}
center={props.center}
defaultZoom={props.zoom}
></GoogleMapReact>
</div>
);
}
Map.defaultProps = {
center: {
lat: 59.95,
lng: 30.33
},
zoom: 11
};
export default Map
// MapContainer.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css';
import Map from './Map'
class MapContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
center: {
lat: 0, lng: 0
}
}
this.getLocation = this.getLocation.bind(this);
this.showPosition = this.showPosition.bind(this);
}
getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.showPosition);
} else {
console.log("Geolocation is not supported by this browser.");
}
}
showPosition(position) {
this.setState({
center: {
lat: position.coords.latitude,
lng: position.coords.longitude
}
});
}
componentDidMount() {
this.getLocation();
}
render() {
return (
<div className="row">
<div className="col-md-9">
<Map center={this.state.center} />
</div>
<div className="col-md-3 d-sm-none d-md-block d-none d-sm-block">
<h1>Menu</h1>
</div>
</div>
);
}
}
export default MapContainer
Looks fine to me. You only need to import 'bootstrap/dist/css/bootstrap.css'; in your main index.js file.
Everything seems good, you are doing right
Is it correct to save lng and lat coords from the GeoLocation API to the MapContainer State?
Is it the correct use of ComponentDidMount() function?
Yeah, Why not ?
What other ways can I improve the code.
there are some minor changes like:
1- you can import Component on top and the class definition would be smaller
2- it is a good practice to use arrow function component definition like this
export default (props) => {
const screenHeight = window.screen.height;
return (
<div style={{ height: screenHeight - 250 }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "AIzaSyCV1fQD2VC6HoNbuuSPkE0q_QZvDf117PY" }}
center={props.center}
defaultZoom={props.zoom}
></GoogleMapReact>
</div>
);
}
generally you are using react in right way, keep going
It looks fine at MapContainer (Example 2) but I propose separate your view based logics and the others. For example, the getLocation function is not based on your view (not depending React component or changing the view) so we can plug out this logic function into an independent function later the showPosition function is going to use that function.

Difference between google-map-react and google-maps-react?

While i'm using Google maps in reactjs, I found two different npms like google-map-react and google-maps-react. As i'm beginner of react i'm bit confused what to use(prefer). Although I found this link but it is bit different which is about- Difference between google-map-react and react-google-maps
The following is the sample code for google-map-react
import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
const AnyReactComponent = ({ text }) => <div>{text}</div>;
class SimpleMap extends Component {
static defaultProps = {
center: {
lat: 59.95,
lng: 30.33
},
zoom: 11
};
render() {
return (
// Important! Always set the container height explicitly
<div style={{ height: '100vh', width: '100%' }}>
<GoogleMapReact
bootstrapURLKeys={{ key: /* YOUR KEY HERE */ }}
defaultCenter={this.props.center}
defaultZoom={this.props.zoom}
>
<AnyReactComponent
lat={59.955413}
lng={30.337844}
text="My Marker"
/>
</GoogleMapReact>
</div>
);
}
}
export default SimpleMap;
The following is the sample code for google-maps-react
import React, { Component } from "react";
import { Map, GoogleApiWrapper, Marker } from "google-maps-react";
const mapStyles = {
width: "100%",
height: "100%"
};
class MapContainer extends Component {
constructor(props) {
super(props);
this.state = {
stores: [
{ lat: 47.49855629475769, lng: -122.14184416996333 },
{ latitude: 47.359423, longitude: -122.021071 },
{ latitude: 47.5524695, longitude: -122.0425407 }
]
};
}
displayMarkers = () => {
return this.state.stores.map((store, index) => {
return (
<Marker
key={index}
id={index}
position={{
lat: store.latitude,
lng: store.longitude
}}
onClick={() => console.log("Clicked me..!")}
/>
);
});
};
render() {
return (
<div>
<Map
google={this.props.google}
zoom={8}
style={mapStyles}
initialCenter={{ lat: 47.444, lng: -122.176 }}
>
{this.displayMarkers()}
</Map>
</div>
);
}
}
export default GoogleApiWrapper({
apiKey: "key"
})(MapContainer);
Please help me Which is optimum to use.
Thanks in advance
As far as I have figured out, google-maps-react mainly focuses on drawing geometric shapes like marker, infowindow, polyline, polygon or circle. They also offer lazy loading for the maps. I have used this library in two of my projects.
On the other hand, google-map-react renders a map where you can put a customized react component in any co-ordinate.
Both libraries can be used to implement API services like autocomplete or direction-services.
You may use any one of them according to your needs.
I wanted to use one of these packages in my project and that's where I created sample projects using both packages so I can test the performance. I wanted to plot thousands of markers and my primary requirement was performance.
I found that google-maps-react handles large markers (>= 10000) of dataset better than google-map-react. Please note for my project, I was not allowed to use clusters and all the markers should be visible all the time on the map. The clustering google-map-react works in a decent way even with larger marker datasets.
It is important to note here that the google-map-react package is updated more frequently than google-maps-react. Avg weekly downloads for google-map-react package are 185,833( 13th July 21) while for google-maps-react average weekly downloads 54,750 ( 13th July 21).
Please note for so many people plotting thousands of markers and relative performance are really important so I decided to write as a separate answer. Apologies for not writing specific performance numbers since I was in hurry.

Pigeon Maps Marker Issue

I am trying to integrate a map in react specifically pigeon-maps since it is an open source.But,I am not able to get the co-ordinates from the map.Can anyone give me some code examples.I have set markers and overlay.I am able to center the map but have no idea how to get the latitude and longitude from the map.
Below is the code for the mapcomponent I am trying to create
import React, { Component } from "react";
import styles from "./mapcomponent.module.css";
import Marker from "pigeon-marker";
import Map from "pigeon-maps";
import Overlay from "pigeon-overlay";
class MapComponent extends Component {
constructor(props) {
super(props);
this.state = { lat: null, long: null };
}
componentWillMount() {
this.setState(
{
lat: Number(this.props.lat),
long: Number(this.props.long)
},
() => {
console.log("HERE", this.state.lat, this.state.long);
}
);
}
render() {
return (
<div className={styles.container} width="500px" height="500px">
<Map center={[this.state.lat, this.state.long]} zoom={12}>
<Marker anchor={[this.state.lat, this.state.long]} payload={1} />
<Overlay
anchor={[this.state.lat, this.state.long]}
offset={[120, 79]}
>
<img src="pigeon.jpg" width={240} height={158} alt="" />
</Overlay>
</Map>
</div>
);
}
}
export default MapComponent;
Can anyone help me to and extend marker and manipulate its value
We have to provide the latitude and longitude to plot the marker on map or you can get latitude and longitude from the map events (like onclick)

react-leaflet get current latlng onClick

I would be realy happy if some one could help me...
I've installed react-leaflet on my react project and the map component is loaded successfully, i need to get current latlng and show it in the Popup when i click on map but I don't know how to :(
please... please... help me...
this is my code
import React from 'react'
import { Map as LeafletMap, TileLayer, Marker, Popup } from 'react-leaflet';
class Mapp extends React.Component {
componentDidMount() {
}
render() {
return (
<LeafletMap
center={[35.755229,51.304470]}
zoom={16}
maxZoom={20}
attributionControl={true}
zoomControl={true}
doubleClickZoom={true}
scrollWheelZoom={true}
dragging={true}
animate={true}
easeLinearity={0.35}
>
<TileLayer
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
<Marker position={[35.755229,51.304470]}
draggable={true}
>
<Popup >
Popup for any custom information.
</Popup>
</Marker>
</LeafletMap>
);
}
}
export default Mapp;
Here is an example on how to display maker position in popup once map is clicked:
class MapExample extends Component {
constructor(props) {
super(props);
this.state = {
currentPos: null
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(e){
this.setState({ currentPos: e.latlng });
}
render() {
return (
<div>
<Map center={this.props.center} zoom={this.props.zoom} onClick={this.handleClick}>
<TileLayer
url='http://{s}.tile.osm.org/{z}/{x}/{y}.png'
/>
{ this.state.currentPos && <Marker position={this.state.currentPos} draggable={true}>
<Popup position={this.state.currentPos}>
Current location: <pre>{JSON.stringify(this.state.currentPos, null, 2)}</pre>
</Popup>
</Marker>}
</Map>
</div>
)
}
}
Explanation:
currentPos state is used to keep marker position
event.latLng property of Map.onClick event handler returns mouse event location
Here is a demo for your reference
What did you try to achieve that?
This will be the start:
Use the click (see https://leafletjs.com/reference-1.4.0.html#map-click) event from the LeafletMap component and call your function, like:
<LeafletMap
center={[35.755229,51.304470]}
zoom={16}
maxZoom={20}
attributionControl={true}
zoomControl={true}
doubleClickZoom={true}
scrollWheelZoom={true}
dragging={true}
animate={true}
easeLinearity={0.35}
onclick={this.handleClick}>
>
...
</LeafletMap>
In your handleClick function you get the information of lat and lng like this:
handleClick = (e) => {
const { lat, lng } = e.latlng;
console.log(lat, lng);
}
From here on, you can create your marker / popup with the information you were looking for.
Additional hint: Please make sure your code is wrapped in correctly in your post..
If you work with react-leaflet version 3.x this does not work. In this case, use the useMapEvents hook in a dummy component that you add to the map. For example, if you want to console.log the clicked position:
const LocationFinderDummy = () => {
const map = useMapEvents({
click(e) {
console.log(e.latlng);
},
});
return null;
};
Then use the LocationFinderDummy in the map as follows:
<MapContainer
center={[0, 0]}
zoom={6}>
<LocationFinderDummy />
</MapContainer>

Resources