0

我的目标是在用户选择地址建议google-maps-react后获得 latlong 后,将地图平移到 latlng 位置。react-places-autocomplete

我在从子功能组件设置地图参考时遇到困难,以便我可以调用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);

这是我的父组件,我想在其中调用 map panto 函数。

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 组件

4

1 回答 1

1

Map.panTo 将地图的中心更改为 Maps JavaScript API 中给定的 LatLng。由于您使用的是google-maps-react库,因此您可以使用反应状态作为该库的中心参数值,以在每次状态更改时更改地图中心的值。在下面的示例代码中,我使用了react-places-autocomplete 入门文档中的代码,并将其与简单的 google-maps-react 代码合并。

这是我声明当前具有值的中心状态的方式:

  state = {
    center: {
      lat: 40.854885,
      lng: -88.081807
    },
    address: ""
  };

这是库中的 handleSelect 事件react-places-autocomplete,它对自动完成中的选定地点进行地理编码。然后你可以看到我将中心的状态设置为地理编码地址的 latLng。

 handleSelect = address => {
    geocodeByAddress(address)
      .then(results => getLatLng(results[0]))
      .then(latLng => this.setState({ center: latLng }))
      .catch(error => console.error("Error", error));
  };

下面是我如何调用 google-maps-react 库的 Map 组件,其中 center 参数的值是名为 center 的状态的值。

<Map
          className="map"
          google={this.props.google}
          onClick={this.onMapClicked}
          center={this.state.center}
          style={{ height: "100%", position: "relative", width: "100%" }}
          zoom={13}
        />

这是一个完整的代码片段和有关我如何合并您使用的 2 个库以在每次您从自动完成中选择地址时更改地图中心的工作代码:

import React, { Component } from "react";
import { Map, GoogleApiWrapper } from "google-maps-react";
import PlacesAutocomplete, {
  geocodeByAddress,
  getLatLng
} from "react-places-autocomplete";
export class MapContainer extends Component {
  state = {
    center: {
      lat: 40.854885,
      lng: -88.081807
    },
    address: ""
  };

  handleChange = address => {
    this.setState({ address });
  };

  handleSelect = address => {
    geocodeByAddress(address)
      .then(results => getLatLng(results[0]))
      .then(latLng => this.setState({ center: latLng }))
      .catch(error => console.error("Error", error));
  };

  render() {
    if (!this.props.loaded) return <div>Loading...</div>;

    return (
      <div>
        <PlacesAutocomplete
          value={this.state.address}
          onChange={this.handleChange}
          onSelect={this.handleSelect}
        >
          {({
            getInputProps,
            suggestions,
            getSuggestionItemProps,
            loading
          }) => (
            <div>
              <input
                {...getInputProps({
                  placeholder: "Search Places ...",
                  className: "location-search-input"
                })}
              />
              <div className="autocomplete-dropdown-container">
                {loading && <div>Loading...</div>}
                {suggestions.map(suggestion => {
                  const className = suggestion.active
                    ? "suggestion-item--active"
                    : "suggestion-item";
                  // inline style for demonstration purpose
                  const style = suggestion.active
                    ? { backgroundColor: "#fafafa", cursor: "pointer" }
                    : { backgroundColor: "#ffffff", cursor: "pointer" };
                  return (
                    <div
                      {...getSuggestionItemProps(suggestion, {
                        className,
                        style
                      })}
                    >
                      <span>{suggestion.description}</span>
                    </div>
                  );
                })}
              </div>
            </div>
          )}
        </PlacesAutocomplete>
        <Map
          className="map"
          google={this.props.google}
          center={this.state.center}
          style={{ height: "100%", position: "relative", width: "100%" }}
          zoom={13}
        />
      </div>
    );
  }
}
export default GoogleApiWrapper({
  apiKey: "YOUR_API_KEY"
})(MapContainer);
于 2020-11-06T07:34:34.180 回答