Как правильно обрабатывать события с Google Map в React Hooks - PullRequest
0 голосов
/ 25 апреля 2020

Я использую Google Map API в своем приложении React (с помощью хуков).

Используется Google Places & Maps API. Пользователь может искать место, после выбора из выпадающего списка карта фокусируется на этом месте. Или пользователь может перетащить / увеличить карту, чтобы получить местоположение.

Код Объяснение:

В приведенном ниже коде, когда пользователь выбирает из выпадающего списка, я сохраняю ограниченную рамку (координаты NE и SW) в родительском компоненте (не показано здесь) состояние. Это вызывает обновление реквизита для этого компонента, который обновляет карту.

Следующий код работает нормально, пока я не добавляю прослушиватель для zoom-changed, потому что прослушиватель для drag-end и ввод для поиска не конфликтуют друг с другом. Однако я хочу добавить также функцию масштабирования, и это срабатывает при выборе поиска, и приложение переходит в бесконечное обновление.

Код:

const ModalGoogleMap = ({ locationSearch, saveLocationSearch, toggleMapModal }) => {
  const defaultCenter = { lat: 51.509865, lng: -0.118092 }
  const defaultZoom = 9;
  const mapDimensions = { width: 900, height: 508 };
  const [gMap, setGMap] = useState();
  const { register } = useForm();
  const searchInputRef = useRef();
  let mapContainerRef = useRef();
  const { address, boundBox } = locationSearch;
  let getPlaces: any;

  useEffect(() => {
    initMap();
    initSearchInput();
  }, []);

  useEffect(() => {
    if (boundBox) {
      const { sw, ne } = boundBox;
      const latlng = new google.maps.LatLngBounds(sw, ne);
      gMap.fitBounds(latlng, 0);
    }
  }, [boundBox]);

  const initMap = () => {
    const gMap = new google.maps.Map(
      mapContainerRef.current,
      {
        zoom: defaultZoom,
        center: defaultCenter
      });
    gMap.addListener("dragend", () => mapEvHandler(gMap));
    // zoom-changed listener is triggered everytime a user searches & selects from search-input 
    gMap.addListener("zoom_changed", () => mapEvHandler(gMap));
    setGMap(gMap);
  };

  const initSearchInput = () => {
    const searchInput = new google.maps.places.SearchBox(searchInputRef.current);
    searchInput.addListener('places_changed', () => {
      getPlaces = searchInput.getPlaces();
      const { formatted_address: address, geometry: { location, viewport } } = getPlaces[0];
      const boundBox = calcNESW(viewport);
      saveLocationSearch({
        address,
        boundBox,
        center: { lat: location.lat(), lng: location.lng() },
        zoom: 12,
      });
    });
  };

  const mapEvHandler = (gMap) => {
    const mapBounds = gMap.getBounds();
    const getCenter = gMap.getCenter();
    const getZoom = gMap.getZoom();
    const boundBox = calcNESW(mapBounds); // func returns NE & SW co-ords
    saveLocationSearch({
      address: `[${getCenter.lat()}, ${getCenter.lng()}]`,
      boundBox,
      zoom: getZoom,
      center: getCenter
    });
  };

Как мне обновить logi c, чтобы не запускать обработчик zoom-changed, если пользователь не запускает с помощью элементов управления масштабированием. Я чувствую, что упускаю важный аспект React Hooks useEffect.

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