Zusman
Zusman

Reputation: 666

onGoogleApiLoaded not rendering when state change

I have a <GoogleMapReact> component, and I render some circles on the map by a list of points, using onGoogleApiLoaded:

const tags = [allJobsTag].concat(settings.jobs.filter((job) => !job.deleted));
const [tag, setTag] = useState(allJobsTag);

function renderGeoFences(map, maps) {
    _.map(geoFencesSites, (site) => {
        let circle = new maps.Circle({
            strokeColor: tag.id==='all-jobs'?"orange":'#1aba8b26',
            strokeOpacity: 1,
            strokeWeight: 4,
            fillColor: '#1aba8b1f',
            fillOpacity: 1,
            map,
            center: { lat: Number(site.location.latitude), lng: Number(site.location.longitude) },
            radius: site.fenceSize,
        });
    });
}




let apiIsLoaded = (map, maps) => {
    renderGeoFences(map, maps);
};

return(
    <GoogleMapReact>
        zoom={getMapZoom()}
        center={{ lat: centerLatitude, lng: centerLongitude }}
        options={{
            fullscreenControl: false,
            zoomControlOptions: { position: 3 },
        }}
        yesIWantToUseGoogleMapApiInternals
        onGoogleApiLoaded={({ map, maps }) => apiIsLoaded(map, maps)}
    >
        {renderAddresses()}
        {renderUsersLocation()}
        {renderHighlightedUserRoute()}
    </GoogleMapReact>
)

and then rendering the circles in renderGeoFences.

However, this function is only called ones, and even though there are states in it, the circles would not be affected by the state. like in this example, when I try to change to color of the circles by the tag.id (tag is a state). How can I make this function render again when a state is changing?

Upvotes: 0

Views: 1109

Answers (2)

Shubham Vishwakarma
Shubham Vishwakarma

Reputation: 136

I suppose you can maintain and googleMapObj which we can use to call isApiLoaded function. And as mentioned below this is called in useEffect.

const tags = [allJobsTag].concat(settings.jobs.filter((job) => !job.deleted));
const [tag, setTag] = useState(allJobsTag);
const [googleApiObj, setIsGoogleApiLoadedObj] = useState(null);

useEffect(() => {
  if (googleApiObj) {
    const {
      map,
      maps
    } = googleApiObj;
    // or else call that isApiLoaded function and pass-on these arguments  
    renderGeoFences(map, maps)
  }
}, [googleApiObj, tag])

function renderGeoFences(map, maps) {
  _.map(geoFencesSites, (site) => {
    let circle = new maps.Circle({
      strokeColor: tag.id === 'all-jobs' ? "orange" : '#1aba8b26',
      strokeOpacity: 1,
      strokeWeight: 4,
      fillColor: '#1aba8b1f',
      fillOpacity: 1,
      map,
      center: {
        lat: Number(site.location.latitude),
        lng: Number(site.location.longitude)
      },
      radius: site.fenceSize,
    });
  });
}

return ( <
  GoogleMapReact >
  zoom = {
    getMapZoom()
  }
  center = {
    {
      lat: centerLatitude,
      lng: centerLongitude
    }
  }
  options = {
    {
      fullscreenControl: false,
      zoomControlOptions: {
        position: 3
      },
    }
  }
  yesIWantToUseGoogleMapApiInternals onGoogleApiLoaded = {
    ({
      map,
      maps
    }) => setIsGoogleApiLoaded({
      map,
      maps
    })
  } >
  {
    renderAddresses()
  } {
    renderUsersLocation()
  } {
    renderHighlightedUserRoute()
  } <
  /GoogleMapReact>
)

Upvotes: 5

Yogesh Yadav
Yogesh Yadav

Reputation: 863

You can re-render using React useEffect hook. In dependency array just give your state tag and now whenever tag changes its state, the useEffect function will runs.

useEffect(() => {
    let apiIsLoaded = (map, maps) => {
    renderGeoFences(map, maps);
};
}, [tag]);

Upvotes: -1

Related Questions