ответная листовка, маркеры перерисовываются при открытии / закрытии всплывающего окна - PullRequest
0 голосов
/ 28 марта 2020

Проблема в том, что каждый раз, когда я нахожу на маркер всплывающее окно, открывается или закрывается, и это заставляет все маркеры перерисовывать, даже если мое состояние не меняется. console.log(myState); запускается каждый раз, когда я наводю курсор на маркер.

Я пытался использовать ловушку useMemo, но не мог понять, как использовать его на country.map. Любая помощь?

Вот мой код:

import React, { useEffect, useState } from 'react';
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';
import { Icon } from 'leaflet';

const myicon = new Icon({
  iconUrl: './icon.svg',
  iconSize: [20, 20]
});

const MyMap = () => {
  const [myState, setMyState] = useState(null);
  const [activePlace, setActivePlace] = useState(null);

  const getData = async () => {
    let response = await axios
      .get('https://corona.lmao.ninja/v2/jhucsse')
      .catch(err => console.log(err));

    let data = response.data;
    setMyState(data);

    // console.log(data);
  };

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

  if (myState) {
    console.log(myState);
    return (
        <Map
          style={{ height: '100vh', width: '100vw' }}
          center={[14.561, 17.102]}
          zoom={1}
        >
          <TileLayer
            attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
            url={
              'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png'
            }
          />

          {myState.map(country => {
            return (
              <Marker
                key={uuidv4()}
                position={[
                  country.coordinates.latitude,
                  country.coordinates.longitude
                ]}
                onmouseover={() => {
                  setActivePlace(country);
                }}
                onmouseout={() => {
                  setActivePlace(null);
                }}
                icon={myicon}
              />
            );
          })}

          {activePlace && (
            <Popup
              position={[
                activePlace.coordinates.latitude,
                activePlace.coordinates.longitude
              ]}
            >
              <div>
                <h4>Country: {activePlace.country}</h4>
              </div>
            </Popup>
          )}
        </Map>
    );
  } else {
    return <div>Nothing</div>;
  }
};

export default MyMap;

1 Ответ

0 голосов
/ 28 марта 2020

Вам даже нужно, чтобы myState был в состоянии? Это может быть просто обычная переменная? Это решит вашу проблему прямо сейчас. Если нет, сделайте копию myState, а затем запустите map () с этим. Вам также понадобится флаг, чтобы определить, следует ли запускать функцию map, поэтому установите хук состояния runMap:

const MyMap = () => {

  // *** Create a FLAG for the map() call
  const [runMap, setRunMap] = useState(false);
  const [activePlace, setActivePlace] = useState(null);

  // setup the data to be function-scoped
  let data;

  const getData = async () => {
    let response = await axios
      .get('https://corona.lmao.ninja/v2/jhucsse')
      .catch(err => console.log(err));

    // just use the data here
    data = response.data;

    // set your runMap flag
    setRunMap(true);
  }

// later on...

if (runMap) {

// ...

  {data.map(country => {

Как примечание, вы не должны вызывая перехватчики таким образом, внутри вложенных функций и всего. Они должны вызываться на верхнем уровне компонента. Честно говоря, есть несколько правил, в вашем случае кажется, что использование компонента на основе классов и замена хука useEffect на componentDidMount может быть более безопасным, а обратная сторона - более многословной.

...