我应该在哪里使用我的React应用程序调用Google地图方法?

时间:2019-01-17 02:08:57

标签: javascript reactjs redux

我正在使用redux来管理我的应用状态,并使用Google地图(或其他地图)来显示我的数据。

我有一个非常复杂的UI,并希望通过redux对其进行管理。但是我在下面有一个问题:

  1. 我有两个组件A和B,它们位于不同的部分,A是一个按钮,B是一个组件,其中包含Google地图,这是一个内部属性,称为“地图”
  2. 单击A时,我想触发map.panBy(-10,-20),结果是中心将被更改,但是通过执行panBy会有动画,在这种情况下(-10, -20)不是结果,它只是偏移量,因此将其(偏移量)保存在商店中并不是一个好主意。我该怎么办?
  3. Solution I:使用redux数据流,调度类似{type:'panBy', payload: [-10, -20]}的操作,当组件B获取数据时,执行map.panBy(-10,-20)。 -> -10,-20是临时参数,存储起来很奇怪。
  4. Solution II:Eventbus,组件A触发事件和组件B对其进行订阅。
  5. Solution III:将map暴露给它的父对象或window对象。 ->也很奇怪...

那么,有解决此问题的通用解决方案吗?

我可以使用redux中间件吗?但是中间件DONOT也知道map

2 个答案:

答案 0 :(得分:1)

如果我对您的理解正确:

  1. 您有一些数据
  2. 您将在地图上显示该数据。

您的问题有一点不清楚-是panBy参数是否是您在redux状态下存储的数据。

以redux状态存储这些参数有点奇怪,因为这些是您一次执行的更多操作,而不是事物的客观数据。

我的意思是-我想您将要存储在状态中的数据类型将是诸如“名称”,“地址”,“纬度”之类的数据,应用这些数据时,它们看起来总是一样。每次您显示“平移”数据时,其显示方式将有所不同。

但是无论如何-如果您只是显示/应用处于redux状态的内容-我将要做的是:

  1. 通过mapStateToProps将redux状态连接到组件
  2. 实施componentDidUpdate,如果mapData已更新,则应用所有相关的地图方法。

但是回到panBy的事情-我建议您应该存储地图中心和缩放级别,而不是存储panBy参数。这样,每次应用时它看起来都一样。

或者,您可以存储原始中心 panBy参数,并使用它们每次重新计算地图。

即。 redux状态如下:

mapState: {

    center: {
     x: 100, 
     y: 200, 
    },
    panBy: {
     x: 10, 
     y: 0
    }    
}

,然后在您的componentDidUpdate中将其更新-并应用平底锅,例如:

componentDidUpdate(prevProps) {
    if (this.props.mapState !== prevProps.mapState) {
         const {mapState} = this.props.mapState; 
         Map.center(mapState.center); 
         Map.panBy(mapState.panBy); 
    }
}

这样做的缺点-每次都需要冗余地重新映射地图,并且根据API的工作方式,它看起来可能很糟糕。

我确实认为更好的解决方案是自己手动重新计算中心-如Spark.Bao所建议。

答案 1 :(得分:1)

同意@dwjohnston,您应该保存喜欢中心的状态并放大redux商店,您的地图至少应具有初始中心,对,该值应为初始状态,例如:

const initialState = {
  center: {
    lat: 100,
    lng: 100
  },
  zoom: ...
}

function mapOptions(state = initialState, action) {
  switch(action.type) {
    ...
  }
}

分派操作后,减速器应根据有效负载修改状态(操作应为{type: "panBy", payload: [-10, -20]}):

function mapOptions(state = initialState, action) {
  switch(action.type) {
    case "panBy":
      const offset = action.payload
      return {
        ...state,
        center: {
          lat: state.center.lat + offset[0],
          lng: state.center.lng + offset[1]
        }
      } 
  }
}

然后您的组件B应该通过新状态更新地图中心。


不知道A组件和B组件分开多远,如果A组件在B组件内部,则从A调用use回调直到到达B,例如:

class A extends React.Component {
  render() {
    <button onClick={()=>this.props.moveMap(-10, -20)}>Move</button>
  }
}

class B extends React.Component {
  componentDidMount() {
    this.map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: -34.397, lng: 150.644},
      zoom: 8
    });
  }

  handleMoveMap = (offsetLng, offsetLat) => {
    this.map.panBy(offsetLng, offsetLat)
  }

  render() {
    <div>
      <div id="map"/>
      <A moveMap={this.handleMoveMap}/>
    </div>
  }
}

否则,您可以选择Solution III,它可以工作并且更方便,但是它不是React模式(数据驱动器UI),而是jQuery模式(手动操作DOM)。 (有时我在React项目中也使用jQuery模式)。

在React和Redux思维中,您应该将共享数据按不同组件放入redux存储中。