Idea on refactor GoogleMap component
Code:
import { useRef, useEffect, useState } from 'react'
import { Wrapper } from '@googlemaps/react-wrapper'
const GoogleMap = ({ center, zoom, libraries = [], onLoad }) => {
const ref = useRef()
const [googleMap, setGoogleMap] = useState(null)
const handleCallback = (status, loader) => {
loader.load().then((google) => {
setGoogleMap(google.maps)
})
}
const initMap = () => {
return new googleMap.Map(ref.current, {
center,
zoom,
})
}
useEffect(() => {
if (googleMap) {
const map = initMap()
const services = {}
libraries.forEach((library) => {
console.log('looping...')
services[library] = new googleMap.places.PlacesService(map) // use services mapping, but I'm too lazy to do that right now
})
onLoad &&
onLoad({
map,
...services,
})
}
}, [googleMap])
return (
<Wrapper apiKey="" libraries={libraries} callback={handleCallback}>
<div
ref={ref}
style={{ width: '100%', height: '950px', margin: '0 auto' }}
>
This is map
</div>
</Wrapper>
)
}
function App() {
const center = { lat: 34.0430058, lng: -118.2673597 }
const zoom = 12
const handleMapLoaded = (services) => {
services.places.nearbySearch(
{
location: center,
radius: '500',
type: ['restaurant'],
},
(results, status) => {
console.log('status:', status)
console.log('results:', results)
}
)
}
return (
<div>
<GoogleMap
center={center}
zoom={zoom}
libraries={['places']}
onLoad={handleMapLoaded}
/>
</div>
)
}
export default App
Why?
- I don't want to use global variable like
windows.google
, look lame for me - It's look plugable, just put library that it support, it will load and return object
- Expose logic of another service, for example nearby places and don't have to put in GoogleMap component anymore
Improvement
- Map marker can render as prop
- More advance component can render as child