I am stuck trying to trigger a re-render of the upon changes in props.
The App.js file initializes state and sets the latitude and longitude to empty strings and the state is updated with the results of an API call. The new values of state are then passed to the for its use in determining the position of the marker on the map.
The challenge I am having now is how to ensure that the newProps received in the component leads to a re-render of the component.
The code in APP.js is as follows
import React from "react"
import './App.css';
import AddressHeader from "./Components/AddressHeader"
import AddressDetails from "./Components/AddressDetails"
import AddressMap from "./Components/AddressMap"
export default function App () {
//State will be created here in the APP.js file and passed to child components via props
const [visitorDetails, setVisitorDetails] = React.useState({
ipAddress : "",
city: "",
timezone: "",
ISP: "",
latitude: "",
longitude: ""
});
React.useEffect(() => { //Fetch data from the API only once, hence the dependencies array has the element 0
fetch("https://geo.ipify.org/api/v2/country,city?apiKey=at_weFpeQS6scjef5CE5Bf9il4OXCNfM")
.then(res => res.json())
.then(data => setVisitorDetails({
ipAddress: data.ip,
city: data.location.city,
timezone: data.location.timezone,
ISP: data.isp,
latitude: data.location.lat,
longitude: data.location.lng
}));
}, [0])
return (
<section>
<AddressHeader />
<AddressDetails
ipAddress = {visitorDetails.ipAddress}
city = {visitorDetails.city}
timezone = {visitorDetails.timezone}
ISP = {visitorDetails.ISP}
/>
<AddressMap
latitude = {visitorDetails.latitude}
longitude = {visitorDetails.longitude}
/>
</section>
)
}
And the code in component is as follows
import React from "react"
import map from "../ComponentStyle/Map.module.css"
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
export default class AddressMap extends React.Component {
constructor () {
super()
this.state = {
latitude: "",
longitude: ""
}
}
shouldComponentUpdate(nextProps, nextState) {
if(nextProps.latitude !== this.props.latitude) {
return true
}
}
render () {
return (
<MapContainer center={[this.state.latitude, this.state.longitude]} zoom={13} scrollWheelZoom={false} className = {map.mapContainer}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position = {[this.state.latitude, this.state.longitude]} >
<Popup>
A test marker and popup
</Popup>
</Marker>
</MapContainer>
)
}
}