yandex map api React как избежать дублей карты

Рейтинг: -1Ответов: 1Опубликовано: 26.02.2023

пытаюсь сделать компонент в котором можно указать адрес на картах но сталкиваюсь с проблемой что не знаю как правильно вызывать функцию Init что бы компонент карт не создавался несколько раз я пытался совершать вызов в useEffect но это не помогало import React, { useState, useEffect } from "react"; import style from "./UserAdress.module.scss";

export const UserAdress = (props) => {
  const [suggest, setSuggest] = useState([]);
  const [adressVariant, setAdressVariant] = useState("");
  const [currentCoordinates, setCurrentCoordinates] = useState([]);
  const HandleSuggest = (e) => {
    ymaps.suggest(e.target.value).then(function (items) {
      setSuggest(items);
    });
  };

  const SetAdress = (e) => {
    setAdressVariant(e.target.textContent);
  };

  const searchAdress = () => {
    ymaps.ready(Init);
    console.log(currentCoordinates);
  };

  const Init = () => {
    let map = new ymaps.Map("map", {
      center: currentCoordinates,
      zoom: 12,
    });
    var myGeocoder = ymaps.geocode(`${adressVariant}`);
    myGeocoder.then(
      function (res) {
        map.geoObjects.add(res.geoObjects);
        setCurrentCoordinates(res.geoObjects.get(0).geometry._coordinates);
      },
      function (err) {}
    );
  };

  useEffect(() => {}, [currentCoordinates]);

  return (
    <div className={style.map}>
      <div className={style.map__inputMenu}>
        <input onChange={(e) => HandleSuggest(e)} />
        <ul>
          {suggest.map((item) => (
            <li onClick={(e) => SetAdress(e)}>{item.value}</li>
          ))}
        </ul>
        <button className={style.map__button} onClick={searchAdress}>
          Проверить
        </button>
      </div>
      <div id="map" style={{ height: "300px", width: "300px" }}></div>
    </div>
  );
};

введите сюда описание изображения

Ответы

▲ 0Принят

Можно инициализировать карту один раз и менять ее центр после загрузки данных. Если есть какие-то начальные координаты, то зависимости для useMemo можно оставить пустыми, иначе, например, можно currentCoordinates инициализировать как null и превратить в boolean, чтобы карта инициализировалась только после первого изменения. Код будет выглядеть примерно так:

const [currentCoordinates, setCurrentCoordinates] = useState(null);

const mapInstance = useMemo(
  () => currentCoordinates
    ? new ymaps.Map('map', {
      center: currentCoordinates,
      zoom: 12,
    })
    : null,
  [!currentCoordinates]
);

useEffect(() => {
  if (!mapInstance || !currentCoordinates) return;
  mapInstance.setCenter(currentCoordinates);
}, [mapInstance, currentCoordinates]);

useEffect(() => {
  if (!mapInstance) return;

  const myGeocoder = ymaps.geocode(`${adressVariant}`);
    myGeocoder.then(
      function (res) {
        mapInstance.geoObjects.add(res.geoObjects);
        setCurrentCoordinates(res.geoObjects.get(0).geometry._coordinates);
      },
      function (err) {}
    );
}, [mapInstance, adressVariant])