Реагируйте на карты Google Маркеры исчезают после повторного рендеринга компонента - PullRequest
0 голосов
/ 07 июня 2018

У меня проблемы с модулем реагировать-google-maps, а именно с маркерами и повторным рендерингом компонентов.

Это сценарий:

  1. Загрузить страницу с картой и 2-3 маркерами на ней (ок)
  2. Нажмите вкладку на панели навигации ->страница отображает что-то еще в одностраничном приложении (ок)
  3. Нажмите вкладку на навигационной панели, которая ведет обратно к карте -> страница отображает карту, но маркеры не отображаются.

Я держу данные маркера в состоянии и применяю их к карте в onGoogleApiLoaded={({map, maps}) => this.renderMarkers(map, maps)}.

Мне удалось решить эту проблему, поместив renderMarkers в setTimeout изодну секунду, и он нормально загружается таким образом.

Мне не нравится это решение, и я считаю, что просто не делаю это так, как должно.Я считаю, что маркеры пытаются разместить себя на карте, которая не отображается, но любопытно, что даже без setTimeout он работает для страницы по умолчанию (вероятно, что-то связанное с жизненным циклом реагирующих компонентов, я не знаю).

Есть ли способ прикрепить свойство onGoogleApiLoaded={({map, maps}) => this.renderMarkers(map, maps)} после полной загрузки карты?Или, по крайней мере, отложить его, пока я не буду на 100% уверен, что карта загружена, а не какое-то случайное число секунд.

РЕДАКТИРОВАТЬ: я назначал маркеры с помощью метода marker.setMap(map), и я просто попытался настроитьсвойство map: map в конструкторе маркера, но поведение остается тем же.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Я понял это после того, как решил проблему немного больше.Проблема была вызвана тем, что я терял данные маркера, которые хранились в состоянии компонента Map (который является дочерним по отношению к компоненту, имеющему панель навигации).

Таким образом, поток былнапример:

  1. Первый рендеринг страницы -> все загружается нормально, потому что все отображается в первый раз (включая маркеры).
  2. Я рендеринг другого компонента, предыдущийуничтожен и теряет состояние.
  3. Я перерисовываю компонент Map, но у него нет состояния, поэтому у него нет данных для маркеров.

Естественно, решение было перенестиукажите родительский уровень на один уровень выше и передайте его как опору компонента карты, и теперь все работает как надо.

БОНУС:

Я хочу упомянутьЕще одна вещь, которую мне пришлось исправить, но она не обязательно будет полезна для других, кто сталкивается с этой проблемой: я использовал навигационную панель для маршрутизации своих страниц (используя react-router-dom).

При перемещении состояния на уровень выше в родительский элемент параметры не будут переданы в элемент <Route, например, так: <Route path="/" component={Map} markerData={this.state.markerData}/>, а, скорее, с использованием свойства render, например: <Route exact path="/" render={props => <Map markerData={this.state.markerData}/>}так что компонент Map получает реквизит, а не Router.

0 голосов
/ 07 июня 2018

Когда вы говорите, что нажимаете на вкладку, и страница отображает что-то еще, вы, вероятно, отключаете компонент карты.Если ваши маркеры сохранены в состоянии, как вы говорите, вы можете проверить это сами в componentWillUnmount .

componentWillUnmount() {
  console.log('Unmount');
}

Если этот журнал консоли отображается в вашей консоли, это означает, что вы 'перемонтируйте ваш компонент и потеряете данные маркеров, которые у вас есть в вашем состоянии.

Теперь, чтобы загрузить карту с вашими маркерами, вы можете дождаться полной загрузки карты с помощью componentDidMount .Я не уверен, чем реагирует-google-maps с реактивной-листовкой (компонентом карты, с которым у меня есть опыт работы), но я предполагаю, что у карты есть свойство, при котором вы передаете ей маркеры, которые вы держите в состоянии.Вместо тайм-аута вам, вероятно, следует использовать componentWillMount или componentDidUnmount метод реакции жизненного цикла, чтобы получить данные маркеров.

componentDidMount() { // It should work with componentWillMount too
  this.fetchMarkersData();
}

fetchMarkersData() {
  // ... get your data
  this.setState({ markers: markersData });
}

render() {
  return (
    <MapComponent
      markers={this.state.markers}
    />
  );
}
...