Как получить ref google-maps -реактивную карту и panto к latlng - PullRequest
0 голосов
/ 07 февраля 2020

Моя цель - панорамировать google-maps-react карту в положение latlng, после получения значения latlong из react-places-autocomplete, когда пользователь выбирает предложение адреса.

Я сталкиваюсь с трудностями при настройке ref для карты из дочернего функционального компонента, поэтому я могу вызвать map.panTo(location) в родительском функциональном компоненте.

Ниже приведены мои Google-Maps и PlaceAutoComplete дочерний элемент. Компонент:

    import React, { useEffect } from 'react';
    import { Map, GoogleApiWrapper, Marker } from 'google-maps-react';
    import { FormGroup, Label, Input, Spinner, Container, Row, Col } from 'reactstrap';
    import PlacesAutocomplete from 'react-places-autocomplete';

    const InputAndMap = React.forwardRef((props, ref) => {
      return (
        <div>
          <PlacesAutocomplete
            value={props.address}
            onChange={props.handleInputChange}
            onSelect={props.handleInputSelect}
          >
            {({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
              <div>
                <FormGroup>
                  <Label for="exampleSearch">Search Address</Label>
                  <Input
                    {...getInputProps({
                      className: 'location-search-input',
                    })}
                    type="search"
                    name="search"
                    id="exampleSearch"
                    placeholder="Enter Store Location"
                  />
                </FormGroup>

                <div className="autocomplete-dropdown-container">
                  {loading && (
                    <div>
                      <Spinner size="sm" color="primary" />
                      Loading...
                    </div>
                  )}
                  {suggestions.map(suggestion => {
                    const className = suggestion.active ? 'suggestion-item--active' : 'suggestion-item';

                    const style = suggestion.active
                      ? { backgroundColor: '#007bff', cursor: 'pointer', color: 'white' }
                      : { backgroundColor: '#ffffff', cursor: 'pointer' };

                    return (
                      <div
                        {...getSuggestionItemProps(suggestion, {
                          className,
                          style,
                        })}
                      >
                        <span>{suggestion.description}</span>
                      </div>
                    );
                  })}
                </div>
              </div>
            )}
          </PlacesAutocomplete>

          <Row className="mb-3" style={{ width: '100%', height: '200px' }}>
            <Col>
              <Map
                id="google-map"
                ref={ref}                                 // <<=== setting ref here
                style={{ width: '100%', height: '200px' }}
                google={props.google}
                zoom={8}
                initialCenter={{ lat: 47.444, lng: -122.176 }}
                onClick={(t, map, e) => props.updateMarker(e.latLng, map)}
              >
                {props.markerLatLong && <Marker position={props.markerLatLong} />}
              </Map>
            </Col>
          </Row>
        </div>
      );
    });

    export default GoogleApiWrapper({
      apiKey: process.env.REACT_APP_GOOGLE_API_KEY,
      libraries: ['places'],
    })(InputAndMap);

Это мой родительский компонент, где я хочу вызвать функцию панорамирования карты.

import React, { useState, useEffect } from 'react';
import { Button, Form, Spinner, Container } from 'reactstrap';
import { Redirect } from 'react-router-dom';
import { geocodeByAddress, getLatLng } from 'react-places-autocomplete';
import firebase from 'firebase/app';
import NavBarMenu from '../components/NavBarMenu';
import InputAndMap from '../components/InputAndMap';
import fire from '../config/fire';

function StoreScreen(props) {
  const [isLoading, setIsLoading] = useState(false);
  const [markerLatLong, setMarkerLatLong] = useState(null);
  const [city, setCity] = useState('');
  const [address, setAddress] = useState('');
  const [redirect, setRedirect] = useState(false);

  const ref = React.createRef();

  const handleInputChange = address => {
    setAddress(address);
  };

  const handleInputSelect = address => {
    setAddress(address);

    geocodeByAddress(address)
      .then(results => {
        processCity(results);
        getLatLng(results[0])
          .then(latLng => {
                console.log('Success', latLng);
                console.log(ref);// ==============> this return {current: null}
                // ref.current.panTo(latLng);// ==> So I am unable to call this
          })
          .catch(error => console.error('Error', error));
      })

      .catch(error => console.error('Error', error));
  };

  return (
    <div>
      <NavBarMenu isShopKeeper />
      <Container className="h-100">
        <Form onSubmit={handleSubmit}>
          <h5 className="text-center">Add Store</h5>

          <InputAndMap
            ref={ref}
            markerLatLong={markerLatLong}
            updateMarker={updateMarker}
            handleInputChange={handleInputChange}
            handleInputSelect={handleInputSelect}
            address={address}
          />

          {isLoading ? (
            <div className="row mx-auto justify-content-center align-items-center flex-column">
              <Spinner color="secondary" />
            </div>
          ) : (
            <Button
              disabled={!markerLatLong || !city || !address}
              className="mb-4"
              color="primary"
              size="lg"
              block
            >
              Add Store
            </Button>
          )}
        </Form>
      </Container>
    </div>
  );
}

export default StoreScreen;

Я также прикрепляю изображение для лучшей визуализации моей проблемы. MapAndInput Component

...