I have the following map.jsx file in my react app, which displays a map on screen. I am trying to add a marker to this map (in a separate component called 'MyGreatPlace') which changes location every 2 seconds. It should just update the marker rather than refreshing the whole map, however i am getting the following error:
Uncaught TypeError: setState is not a function
Below is my code:
import GoogleMapReact from 'google-map-react';
import './map.css';
import MyGreatPlace from './my_great_place.jsx';
import React, { useEffect, useRef, useState, setState } from 'react';
const Map = ({ location, zoomLevel, markerLat, markerLong }) => {
useEffect(() => {
const interval = setInterval(() => {
changeMarkerLatitude();
}, 2000);
return () => clearInterval(interval);
}, []);
const changeMarkerLatitude = () => {
setState({
markerLat: markerLat + 50,
});
};
return (
<div className='map'>
<div className='google-map'>
<GoogleMapReact
bootstrapURLKeys={{ key: 'KeyID' }}
defaultCenter={location}
defaultZoom={zoomLevel}>
<MyGreatPlace lat={markerLat} lng={markerLong} text={'A'} />
</GoogleMapReact>
</div>
</div>
);
};
export default Map;
Does anyone know how i can fix this error, or is there an alternative way of updating the marker location?
That's not how you use the state objects. useState is for functional components, and you invoke it by providing two values. First, the reference to the actual value, and second - the reference to the setter. So const [stateVal, setStateVal] = useState() gives you an undefined reference to a state object, and a reference to a function for updating it. You NEVER mutate the state directly (e.g. stateVal = newVal). You ALWAYS use the setter to mutate the state (which triggers a rerender). You can always initialize the value by passing a value into the useState() call. Like this: setStateVal(newVal)
import GoogleMapReact from 'google-map-react';
import './map.css';
import MyGreatPlace from './my_great_place.jsx';
import React, { useEffect, useRef, useState, setState } from 'react';
const Map = ({ location, zoomLevel, markerLat, markerLong }) => {
const [markerLatVal, setMarkerLatVal] = useState(markerLat) // You can put value in here to initialize
useEffect(() => {
const interval = setInterval(() => {
changeMarkerLatitude();
}, 2000);
return () => clearInterval(interval);
}, []);
const changeMarkerLatitude = () => {
// 'prev' gives you access to the previous state value
setMarkerLatVal(prev => prev + 50);
};
return (
<div className='map'>
<div className='google-map'>
<GoogleMapReact
bootstrapURLKeys={{ key: 'KeyID' }}
defaultCenter={location}
defaultZoom={zoomLevel}>
<MyGreatPlace lat={markerLat} lng={markerLong} text={'A'} />
</GoogleMapReact>
</div>
</div>
);
};
export default Map;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>