I have a component called GoogleMap.js
. I want to import it if user scrolls, so I made it lazy import but it doesn't return JSX. Instead it returns React.lazy
object. So I cannot render it in JSX. How can I render it with in JSX. Also, if I use it like that, does it import react google map even though use doesn't scroll the page.
import React from 'react'
import GoogleMapReact from 'google-map-react'
import styled from 'styled-components'
const GoogleMapWrapper = styled.div`
height: 40vh;
width: 60vw;
margin: 50px auto;
border: 1px solid red;
`
function GoogleMap() {
return (
<GoogleMapWrapper>
<GoogleMapReact
bootstrapURLKeys={{ key: 'AIzaSyAER*******************zs0' }}
defaultCenter={{
lat: -3.745,
lng: -38.523
}}
defaultZoom={3}
>
<div
lat={59.955413}
lng={30.337844}
text="My Marker"
/>
</GoogleMapReact>
</GoogleMapWrapper>
)
}
export default GoogleMap
useEffect(() => {
if (isImported) {
window.removeEventListener('scroll', scrollDetector)
const GoogleMap = React.lazy(() => import('../../components/DynamicLandingPages/GoogleMap'))
console.log("type:", typeof GoogleMap)
console.log("OBJ:", GoogleMap)
setGoogleMapComponent(GoogleMap)
}
}, [isImported])
Note: googleMapComponent is a react state. Set is its setter function.
<Suspense fallback={<GoogleMapWrapper />}>
<googleMapComponent />
</Suspense>
Here is what it returns:
{$$typeof: Symbol(react.lazy), _status: -1, _result: null, _ctor: ƒ, …}
You are abusing React state. You shouldn't keep components as state !
Also, this <googleMapComponent />
is wrong. More details in docs.
Finally, is there any reason for using React.lazy
in useEffect
?
It should be used something like this:
// some MyComponent.js file
// ... normal imports ...
const GoogleMap = React.lazy(() => import('../../components/DynamicLandingPages/GoogleMap'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<GoogleMap />
</Suspense>
</div>
);
}
If you need something to be rendered when you scroll to certain position, than you might want add some state - something like isElementInViewport
, you need a piece of JS to actually figure that out and set that state to true
when it happens and then you can do stuff like:
{isElementInViewport
&& (Suspense fallback={<div>Loading...</div>}>
<GoogleMap />
</Suspense>)}