Где я могу назвать методы карты Google в своем приложении реакции? - PullRequest
0 голосов
/ 17 января 2019

Я использую Redux для управления состоянием своего приложения и использую карту Google (или другую карту) для отображения моих данных.

У меня очень сложный пользовательский интерфейс, и я хочу управлять им с помощью redux. Но у меня есть вопрос ниже:

  1. У меня есть два компонента A и B, они находятся в отдельных частях, A - это кнопка, B - это компонент с картой Google в нем как внутреннее свойство, называемое «map»
  2. Когда нажмите A, я хочу вызвать map.panBy(-10,-20), в результате будет изменен центр, но при выполнении panBy появляется анимация, в этом случае (-10, -20) не результат, это просто смещение, поэтому сохранять его (смещение) в магазине не очень хорошая идея. Что мне делать?
  3. Solution I: используя поток избыточных данных, отправьте действие, подобное {type:'panBy', payload: [-10, -20]}, и, когда компонент B получит данные, выполните map.panBy(-10,-20). -> -10, -20 - временные параметры, хранить их странно.
  4. Solution II: Eventbus, триггерное событие компонента A и компонент B подписываются на него.
  5. Solution III: выставить map его родителю или объекту window. -> странно тоже ...

Итак, есть ли общее решение для решения этой проблемы?

Можно ли использовать промежуточное программное обеспечение для редуксов? Но промежуточное ПО НЕ ДОЛЖНО знать map.

Ответы [ 2 ]

0 голосов
/ 17 января 2019

согласен с @dwjohnston, вы должны сохранить центр лайков штата и увеличить масштаб в магазине редуксов, у вашей карты должен быть хотя бы начальный центр, верно, это значение должно быть вашим начальным состоянием, например:

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, вы вызываете функцию callback из A до тех пор, пока он не достигнет 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 работает вручную). (иногда я использую шаблон jQuery в своем проекте React).

в мышлении React и Redux вы должны поместить совместно используемые данные различными компонентами в хранилище приставок.

0 голосов
/ 17 января 2019

Если я вас правильно понимаю:

  1. У вас есть данные
  2. Вы собираетесь отобразить эти данные на карте.

Что немного неясно в вашем вопросе - это то, являются ли параметры panBy данными, которые вы храните в своем состоянии избыточности.

Немного странно, что вы сохранили бы эти параметры в состоянии избыточности, потому что это больше действий, которые вы делаете один раз, а не объективные данные о чем-либо.

То, что я имею в виду, - данные, которые, я думаю, вы будете хранить в состоянии, будут такими, как «имя», «адрес», «широта», данными, которые всегда будут выглядеть одинаково при применении. Принимая во внимание, что данные панорамирования будут отображаться по-разному каждый раз, когда вы их отображаете.

Но в любом случае - если вы просто отображаете / применяете все, что у вас есть в вашем состоянии избыточности - я бы сделал следующее:

  1. Подключить состояние редукса к компоненту через mapStateToProps
  2. Реализуйте componentDidUpdate, и если mapData обновился, то примените все соответствующие методы карты.

Но вернемся к вопросу panBy - я бы посоветовал вместо хранения параметров panBy хранить центр карты и уровень масштабирования. Таким образом, он будет выглядеть одинаково каждый раз, когда вы его применяете.

Кроме того, вы можете сохранить исходные параметры центра и panBy и использовать их, чтобы каждый раз пересчитывать карту.

т. состояние притока:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...