使用onBoundsChanged反应Google Maps重新渲染问题

时间:2019-02-06 20:19:05

标签: javascript reactjs react-google-maps

我有一个我正在使用React Google Maps的项目,但是遇到一个问题,当我收到onBoundsChanged事件并在回调中设置状态时,它进入了重新渲染的永久循环。我只能以某种方式假设,当组件在调用setState之后重新呈现时,它会设置一个新的界限,然后将以无限递归循环的形式重新触发回调和setState

import React from 'react'
import { compose, withProps, withStateHandlers, withState, withHandlers } from "recompose";
import {
  withScriptjs,
  withGoogleMap,
  GoogleMap,
  Marker
} from"react-google-maps";
import HouseDetails from './house/HouseDetails'
const { InfoBox } = require("react-google-maps/lib/components/addons/InfoBox");

class Map extends React.Component{
  constructor(props){
    super(props)
    this.state = {
      zoom: 15,
      bounds: null    
    }
    this.map = React.createRef()
    this.onBoundsChanged = this.onBoundsChanged.bind(this)
    this.onZoomChanged = this.onBoundsChanged.bind(this)
  }
  componentWillReceiveProps(test){
  }
  onBoundsChanged(){
    this.setState({bounds: this.map.current.getBounds()}, ()=> console.log('update'))
    let bounds = this.map.current.getBounds()
    let realBounds = {lat:{west: bounds.ga.j, east: bounds.ga.l}, lon: {north: bounds.ma.j, south: bounds.ma.l}}
    console.log(realBounds) 

  }
  onZoomChanged(){
    this.setState({zoom: this.map.current.getZoom()})
  }
  componentDidUpdate(){
    console.log('hm')
  }
  render(){
    return (
    <GoogleMap
        defaultZoom={15}
        ref={this.map}
        onZoomChanged={this.onZoomChanged}
        onBoundsChanged={this.onBoundsChanged}
        center={{ lat: 21.493468, lng: -3.177552}}
        defaultCenter={this.props.center}>
    </GoogleMap>
    )
  }
}

export default withScriptjs(withGoogleMap(Map))

上面重新渲染为无穷大的组件的代码,只要我没有在setState函数中onBoundsChanged,它就不会出错。有什么办法解决吗?

2 个答案:

答案 0 :(得分:1)

我正在使用react-google-maps。

如果要在拖动地图时在新位置更新标记,可以使用onBoundsChanged道具

<GoogleMap
        ref={refMap}
        defaultZoom={13}
        defaultCenter={{ lat: center.lat, lng: center.lng }}
        onBoundsChanged={handleBoundsChanged}
        fullscreenControl={false}
        defaultOptions={defaultMapOptions}
        onDragEnd={handleDragend}
      >
        <Marker position={center} />
      </GoogleMap>

并在handleBoundsChanged中,您可以使用新的经纬度更新中心

const handleBoundsChanged = () => {
    console.log("handleBoundsChanged")
    const lat = refMap.current.getCenter().lat()
    const lng = refMap.current.getCenter().lng()
    const mapCenter = {
      lat: lat,
      lng: lng,
    }
    setCenter(mapCenter); // move the marker to new location
  };

如果您想以编程方式将地图移动到新的经纬度,则可以在地址更新时在useEffect中使用panTo函数。当您在搜索中输入地址并且希望将地图和标记放置在新位置时,这是必需的

//on address update
  useEffect(() =>{
    console.log("props updates", props.address, props.locationName)
    if(props.address.source == 'searchbar'){
      console.log("in the searchbar props")
      const mapCenter = {
        lat: props.address.latitude,
        lng: props.address.longitude,
      }
      refMap.current.panTo(mapCenter) //move the map to new location
      setCenter(mapCenter) // move the marker to new location
    }
  },[props.address])

答案 1 :(得分:0)

我从docs撰写示例转换了上面的类,我肯定在某个地方搞砸了,因为我的错误非常明显,因为在渲染时为GoogleMap对象设置了中心,所以我要做的就是将初始状态设置为一个位置,设置默认状态,然后从组件中删除“中心”道具,这意味着在重新渲染时不会将其拉回到中心,因此不会重新触发onBoundsChanged