React - компонент Google Maps не отображается после componentDidMount

У меня просто проблемы с рендерингом Google Maps, когда происходит поиск (с почтовым индексом). Похоже, что карта отображает нулевой центр карты, а затем не выполняет повторную визуализацию после setState в componentDidMount(), поскольку карта отображается пустой/серой, но при жестком обновлении карта будет загружаться с почтовым индексом. Я безуспешно пытался использовать componentWillMount(), у кого-нибудь есть предложения?

Это код моей страницы поиска:

class SearchContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      map_centre: null
    };
  }

  componentDidMount() {
    const values = queryString.parse(this.props.location.search);
    axios
      .get("api/v1/search?postcode=" + values.postcode)
      .then(response => {
        var mapCentre = response.data.map_centre;
        this.setState({
          map_centre: mapCentre
        });
      })
      .catch(error => console.log(error));
  }

  render() {
    return (
      <div id="map" className="padding-left">
        <GoogleMapComponent
          townCenters={this.state.townCenters}
          schools={this.state.schools}
          supermarkets={this.state.supermarkets}
          hotels={this.state.hotels}
          airports={this.state.airports}
          trainStations={this.state.trainStations}
          map_centre={this.state.map_centre}
          onMapMounted={this.handleMapMounted}
          onDragEnd={this.handleMapChange}
          onZoomChanged={this.handleMapChange}
          onMarkerClick={this.handleAdspaceShow}
          googleMapURL={url}
          loadingElement={<div style={{ height: `100vh`, width: `100%` }} />}
          containerElement={<div style={{ height: `100vh`, width: `100%` }} />}
          mapElement={<div style={{ height: `100vh`, width: `100%` }} />}
        />
        <img
          src={mapSearch}
          id="map-search-button"
          onClick={this.toggleSearchInput}
        />
        <input
          id="map-search-input"
          className="form-control d-none"
          type="search"
          placeholder="Enter new location"
          aria-label="Search"
          onChange={this.handlePostcodeChange}
          onKeyPress={this.handleNewSearch}
        />
      </div>
    );
  }
}

Это код для моего компонента Google Maps:

const GoogleMapComponent = withScriptjs(
  withGoogleMap(props => (
    <GoogleMap
      defaultZoom={13}
      defaultCenter={props.map_centre}
      onDragEnd={props.onDragEnd}
      onZoomChanged={props.onZoomChanged}
      ref={props.onMapMounted}
    />
  ))
);

person Shirley Deng    schedule 31.07.2018    source источник
comment
Вы пытались использовать реквизит center вместо map_centre в компоненте GoogleMapComponent?   -  person Tholle    schedule 31.07.2018
comment
@Tholle, не могли бы вы пояснить, что вы имеете в виду?   -  person Shirley Deng    schedule 31.07.2018
comment
Я сам не использовал эту библиотеку, но просматривал документацию GoogleMap компонент, похоже, не имеет реквизита map_centre, но имеет реквизит center.   -  person Tholle    schedule 31.07.2018
comment
Я думаю, что это немного отличается, так как я не жестко кодирую defaultCenter. Я получаю defaultCenter в моей функции componentDidMount   -  person Shirley Deng    schedule 31.07.2018
comment
Да, но вы передаете значение, полученное из запроса axios как map_centre, на карту. Карта не знает, что делать с map_centre, только с center.   -  person Tholle    schedule 31.07.2018
comment
Но map_centre — это просто имя штата, и вы можете видеть, что оно отслеживается до фактического компонента GoogleMap в defaultCenter, с которым карта на самом деле что-то делает?   -  person Shirley Deng    schedule 31.07.2018
comment
Да, вы правы, но defaultCenter это только начальный центр. Он больше не будет использоваться картой после первоначального рендеринга. Если вместо этого вы используете center на GoogleMap, он, скорее всего, обновится, как и ожидалось.   -  person Tholle    schedule 31.07.2018
comment
А, понял, думал, что будет после каждого рендера. Большое спасибо!   -  person Shirley Deng    schedule 31.07.2018
comment
Большой! Пожалуйста.   -  person Tholle    schedule 31.07.2018
comment
Рассмотрите возможность принятия моего ответа, если вы считаете, что он отвечает вашим вопрос.   -  person Tholle    schedule 02.08.2018


Ответы (2)


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

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

const GoogleMapComponent = withScriptjs(
  withGoogleMap(props => (
    <GoogleMap
      defaultZoom={13}
      center={props.map_centre}
      onDragEnd={props.onDragEnd}
      onZoomChanged={props.onZoomChanged}
      ref={props.onMapMounted}
    />
  ))
);
person Tholle    schedule 31.07.2018

Будьте более конкретны с библиотекой, которую вы используете... вы добавили теги "google-maps-react" и "react-google-map", и обе являются разными библиотеками...

google-maps-react = https://github.com/fullstackreact/google-maps-react< /а>

react-google-map = https://tomchentw.github.io/react-google-maps/

В любом случае я вижу 2 варианта:

решение 1:

Добавьте условие, которое отображает GoogleMapComponent только в том случае, если map_centre не равен нулю.

  render() {
    if(this.state.map_centre){
      return (
        <div id="map" className="padding-left">
          <GoogleMapComponent
            townCenters={this.state.townCenters}
            schools={this.state.schools}
            supermarkets={this.state.supermarkets}
            hotels={this.state.hotels}
            airports={this.state.airports}
            trainStations={this.state.trainStations}
            map_centre={this.state.map_centre}
            onMapMounted={this.handleMapMounted}
            onDragEnd={this.handleMapChange}
            onZoomChanged={this.handleMapChange}
            onMarkerClick={this.handleAdspaceShow}
            googleMapURL={url}
            loadingElement={<div style={{ height: `100vh`, width: `100%` }} />}
            containerElement={<div style={{ height: `100vh`, width: `100%` }} />}
            mapElement={<div style={{ height: `100vh`, width: `100%` }} />}
           />
          <img
          src={mapSearch}
          id="map-search-button"
          onClick={this.toggleSearchInput}
          />
          <input
          id="map-search-input"
          className="form-control d-none"
          type="search"
          placeholder="Enter new location"
          aria-label="Search"
          onChange={this.handlePostcodeChange}
          onKeyPress={this.handleNewSearch}
          />
      </div>);
     }
     return <div> Loading.. </div>;
  }

решение 2:

Установите широту/долготу по умолчанию (не нуль), прежде чем вы получите ответ.

constructor(props) {
    super(props);
    this.state = {
      map_centre: { lat: -34.397, lng: 150.644 }
    };
  }
person Mikjail Salazar    schedule 30.09.2018