i am stuck in issue i couldn't resolve it. i am making choropleth with react leaflet. The issue is my API data is not working in highlightFeature function which assigning it to onEachFeature. when i console the api data i get it fine outside the highlightFeature function. but it doesn't work inside highlightFeature function where i need it be worked. can anyone help me ? please check below code. Thanks in advance.
Note: if i use local json data i mean created hard coded manually it works fine. only my api data is not working under this function highlightFeature. code sandbox link is here https://codesandbox.io/s/boring-pine-w0y9vu?file=/src/Map.js
CodePudding user response:
It seems Like the onEachFeature takes the function Copy while the initial load and execute the function separately. so the Post value updated does not result in the onEachFeature function. I don't know how exactly fix the issue. but the workaround is you can addLoader until the Data is fetched and then render the Map Component, that will fix your issue.
import React, { useState } from "react";
import "leaflet/dist/leaflet.css";
import { MapContainer, TileLayer, GeoJSON } from "react-leaflet";
import features from "./country";
import "./Map.css";
import axios from "axios";
import { LocalData } from "./LocalData";
const baseURL = "https://jsonplaceholder.typicode.com/posts/1";
const Map = () => {
const [onselect, setOnselect] = useState({});
const [post, setPost] = React.useState(null);
const [loading, setLoading] = React.useState(false);
React.useEffect(() => {
setLoading(true);
axios.get(baseURL).then((response) => {
setPost(response.data);
// Added Loader..
setLoading(false);
});
}, []);
const highlightFeature = (e) => {
console.log({ post }, "in");
console.log({ LocalData }, "in");
var layer = e.target;
const {
County,
Total,
Male,
Female,
Intersex,
Desnity
} = e.target.feature.properties;
setOnselect({
county: County,
total: Total,
male: Male,
female: Female,
intersex: Intersex,
density: Desnity
});
layer.setStyle({
weight: 1,
color: "black",
fillOpacity: 1
});
};
const resetHighlight = (e) => {
setOnselect({});
e.target.setStyle(style(e.target.feature));
};
const onEachFeature = (feature, layer) => {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight
});
};
const mapPolygonColorToDensity = (density) => {
return density > 3023
? "#a50f15"
: density > 676
? "#de2d26"
: density > 428
? "#fb6a4a"
: density > 236
? "#fc9272"
: density > 23
? "#fcbba1"
: "#fee5d9";
};
const style = (feature) => {
return {
fillColor: mapPolygonColorToDensity(feature.properties.Desnity),
weight: 1,
opacity: 1,
color: "white",
dashArray: "2",
fillOpacity: 0.5
};
};
const mapStyle = {
height: "55vh",
width: "85%",
margin: "0 auto"
};
const feature = features.map((feature) => {
return feature;
});
return (
<div className="container">
<div className="header">
<h2 className="heading">
Kenya Population as Per 2019 National Census Exercise
</h2>
<p className="text-muted">
A choropleth map displaying Kenya population density as per the
national census conducted <br />
in 2019 Each County, details displayed by the map include, total
population and number of each gender.
</p>
</div>
<div className="">
<div className="">
{!onselect.county && (
<div className="census-info-hover">
<strong>Kenya population density</strong>
<p>Hover on each county for more details</p>
</div>
)}
{onselect.county && (
<ul className="census-info">
<li>
<strong>{onselect.county}</strong>
</li>
<br />
<li>Total Population:{onselect.total}</li>
<li>Men:{onselect.male}</li>
<li>Women:{onselect.female}</li>
<li>Intersex:{onselect.intersex}</li>
<li>
Population density:{onselect.density} people <br /> per square
km
</li>
</ul>
)}
<MapContainer
zoom={6}
scrollWheelZoom={true}
style={mapStyle}
center={[1.286389, 38.817223]}
>
<TileLayer
attribution="Map tiles by Carto, under CC BY 3.0. Data by OpenStreetMap, under ODbL."
url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png"
/>
// Load Geojson after getting data..
{feature && !loading && (
<GeoJSON
data={feature}
style={style}
onEachFeature={onEachFeature}
/>
)}
</MapContainer>
</div>
</div>
</div>
);
};
export default Map;