英文:
How to stop reloading the google map when the state is changes in React?
问题
我有一个React应用,其中包含一个Google地图组件。
这个:
```jsx
<GoogleMap
center={center}
zoom={3}
onLoad={(map) => setMap(map)}
mapContainerStyle={{ width: '100%', height: '100%' }}
>
{data.toDisplayOnMap.length > 0 && (
<>
{data.toDisplayOnMap.map((element, i) => {
if ('events' in element.item) {
return <Marker key={i} position={element.item.locationCoords} onClick={() => navigate(`/location?id=${element.id}`)} icon={`http://labs.google.com/ridefinder/images/mm_20_red.png`} />
} else if ('waypoints' in element.item) {
if (element.item.traveltype === 'location') {
return <DirectionsRenderer options={{ preserveViewport: true, polylineOptions: { strokeColor: 'blue', strokeWeight: 2 }, markerOptions: { icon: `http://labs.google.com/ridefinder/images/mm_20_yellow.png` } }} directions={element.route} />
} else {
let wps = element.item.waypoints;;
let coords = [];
wps.forEach((wp) => {
wp.coords.forEach((coord) => {
coords.push(coord)
})
})
return (<>
<Marker position={coords[0]} icon={`http://labs.google.com/ridefinder/images/mm_20_yellow.png`} />
<Marker position={coords[coords.length - 1]} icon={`http://labs.google.com/ridefinder/images/mm_20_yellow.png`} />
<Polyline path={coords} options={{ geodesic: true, strokeColor: '#000', strokeOpacity: 1, strokeWeight: 2, editable: false, draggable: false, clickable: true }} />
</>)
}
}
})}
</>
)}
</GoogleMap>
发生的情况是,我有一个对象列表,如果人们选中复选框,则会显示在地图上,但我的中心在非洲,缩放为3,以便我可以看到大部分地图。如果我放大以查看那个标记或折线,然后取消选中复选框,它会重新加载地图并将我移回非洲。我真的不知道如何使用useMemo之类的东西,因为显示在我的地图上的内容来自页面的状态。我尝试过useMemo,但可能用错了,因为它什么都没做。而且在我的控制台中我有这个
253 useJsApiLoader.tsx:62 Performance warning! LoadScript has been reloaded unintentionally!
这是我声明地图的方式:
const [map, setMap] = useState(/** @type google.maps.Map */(null))
const { isLoaded } = useJsApiLoader({
googleMapsApiKey: ct.MAPS_API_KEY,
libraries: p
})
请帮我解决这个问题。
<details>
<summary>英文:</summary>
I have a React app and I have a Google Map Component.
This one:
<GoogleMap
center={center}
zoom={3}
onLoad={(map) => setMap(map)}
mapContainerStyle={{ width: '100%', height: '100%' }}
>
{data.toDisplayOnMap.length > 0 && (
<>
{data.toDisplayOnMap.map((element, i) => {
if ('events' in element.item) {
return <Marker key={i} position={element.item.locationCoords} onClick={() => navigate(`/location?id=${element.id}`)} icon={`http://labs.google.com/ridefinder/images/mm_20_red.png`} />
} else if ('waypoints' in element.item) {
if (element.item.traveltype === 'location') {
return <DirectionsRenderer options={{ preserveViewport: true, polylineOptions: { strokeColor: 'blue', strokeWeight: 2 }, markerOptions: { icon: `http://labs.google.com/ridefinder/images/mm_20_yellow.png` } }} directions={element.route} />
} else {
let wps = element.item.waypoints;;
let coords = [];
wps.forEach((wp) => {
wp.coords.forEach((coord) => {
coords.push(coord)
})
})
return (<>
<Marker position={coords[0]} icon={`http://labs.google.com/ridefinder/images/mm_20_yellow.png`} />
<Marker position={coords[coords.length - 1]} icon={`http://labs.google.com/ridefinder/images/mm_20_yellow.png`} />
<Polyline path={coords} options={{ geodesic: true, strokeColor: '#000', strokeOpacity: 1, strokeWeight: 2, editable: false, draggable: false, clickable: true }} />
</>)
}
}
})}
</>
)}
</GoogleMap>
Well what is happening is I have a list of objects and if people are checking a Checkbox it is displayed on the map, but my center is in Africa and a zoom of 3 so I can get the most of the map. If I zoom in to see that Marker or that PolyLine and then I deselect the checkbox, it reloads the map and move me back to Africa. I don't really know how can I use this with a useMemo or something like that because What is displayed on my map it's coming from the state of the page. I tried useMemo, but probably I used it wrong because it was doing nothing. And also in my console I have this
253 useJsApiLoader.tsx:62 Performance warning! LoadScript has been reloaded unintentionally!
This is how I declared my map:
` const [map, setMap] = useState(/** @type google.maps.Map */(null))`
const { isLoaded } = useJsApiLoader({
googleMapsApiKey: ct.MAPS_API_KEY,
libraries: p
})
Please help me fix this.
</details>
# 答案1
**得分**: 1
你可以使用React的`useMemo`钩子来防止组件重新渲染。你可以这样使用`useMemo`:
```jsx
const renderGoogleMap = useMemo(() => {
return <GoogleMap {...props} />;
}, []);
然后调用这个记忆函数:
<div>
{renderGoogleMap}
</div>
你也可以将依赖项传递给useMemo
钩子,以在这些依赖项发生更改时允许重新渲染视图。
英文:
you can use react hook useMemo to prevent re-rendering of components. You can use useMemo this way
const renderGoogleMap = useMemo(() => {
return <GoogleMap {...props} />;
}, []);
and call this memoize function as
<div>
{renderGoogleMap}
</div>
you can also pass deps to useMemo hook on change of that deps you can allow to re-render the view.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论