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?
CodePudding user response:
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>