DEV Community

Cover image for Criando mapas utilizando Leaflet via CDN em um projeto React
Martin Sch
Martin Sch

Posted on • Originally published at inventordigital.wordpress.com

Criando mapas utilizando Leaflet via CDN em um projeto React

Estava trabalhando em um projeto onde teria que ser exibido um mapa com pontos agrupados (marker clusters). O Leaflet é com certeza uma ótima solução para isso. Existem duas opções para adicionar o Leaflet, por npm (react-leaft) ou via CDN. A segunda opção é mais vantajosa já que o mapa só seria apresentado em uma página e adicionar-lo em npm faz o projeto aumentar de tamanho e o build ficar mais lento.

cluster map example


Como importar o leaflet?

Segundo a documentação, você tem que importar o CSS e o JavaScript, exatamente nessa ordem:

Imagem mostrando um treco da documentação.

Na hora que for carregar o componente, é possível fazer a mesma coisa "injetando" o <link> e <script> utilizando:

// função para adicionar a tag link
const insertLinkCSS = (cssUrl, key = '', id) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = cssUrl
      if (id.length > 0) {
        link.id = id
      }
      if (key.length > 0) {
        link.integrity = key
      }
      link.crossOrigin = ''
      document.body.appendChild(link)
}

//função para adicionar a tag script
const insertScriptSrc = (scriptUrl, key = '', id) => {
      const script = document.createElement('script')
      script.type = 'text/javascript'
      script.src = scriptUrl
      if (id.length > 0) {
        script.id = id
      }
      if (key.length > 0) {
        script.integrity = key
      }
      script.async = false
      script.crossOrigin = ''
      document.body.appendChild(script)
}

Em seguida são chamadas as funções passando o import no inicio do componente:

useEffect(() => {
   insertLinkCSS(
      'https://unpkg.com/leaflet@1.7.1/dist/leaflet.css',
      'sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==',
    )
    insertScriptSrc(
      'https://unpkg.com/leaflet@1.7.1/dist/leaflet.js',
      'sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==',
    )
  })

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <div id='mapid'> </div>
      </header>
    </div>
  );

Dessa forma as tags de import aparecem no html da página.

Repare que estou adicionando um id para cada elemento e eu já vou mostrar o motivo disso.

Esperando os imports serem carregados

Antes começar a utilizar, é necessário garantir que os elementos foram carregados antes de começar a configurar o mapa. Uma forma de resolver isso é criar uma forma de verificar quando o <link> e o <script> aparecem no document:

//Define todos os ids que precisam ser verificados
const elementsIdConst = {
    LEAFTLET_CSS: 'leafletcss',
    LEAFTLET_JS: 'leafletjs',
    MAP_ID: 'mapid',
  }

function waitLoadElementsById(elementsId, callBack) {
    const formatedArray = elementsId.map(item => `#${item}`)

    //cria um setInterval para verificar a cada 100 milissegundos
    var elementsExists = setInterval(function () {
      if (document.querySelectorAll(formatedArray).length === elementsId.length) {
        try {
          callBack()
        } catch (e) {
          throw e
        }

        //Se achou todos os elementos, para o setInterval e o setTimeout
        clearInterval(elementsExists)
        clearTimeout(timeout)
      }
    }, 100)

    //timeout para para de rodar o setInterval depois de um tempo
    const timeout = setTimeout(() => {
      clearInterval(elementsExists)
    },5000)
  }


useEffect(() => {

   //chama o import do CSS com o id
   insertLinkCSS(
      'https://unpkg.com/leaflet@1.7.1/dist/leaflet.css',
      '',
      elementsIdConst.LEAFTLET_CSS,
    )

   //chama o import do script com o id
    insertScriptSrc(
      'https://unpkg.com/leaflet@1.7.1/dist/leaflet.js',
      '',
      elementsIdConst.LEAFTLET_JS,
    )

    //Com os elementos carregados, chama a função para iniciar o mapa
    waitLoadElementsById(Object.values(elementsIdConst), () => renderMap())
  })

Código completo

Para ter mais detalhes sobre a implementação você pode ver o código com repositório.


Conclusão

Utilizando um lib JavaScript via CDN pode ser um pouco mais "complicado" mas pode trazer muitas vantagens para um projeto que pretende escalar, pois você tem muito mais controle dos recursos utilizados e garante que eles só serão carregados na sua aplicação nos momentos certos. Se a sua aplicação é mais simples, então vale a pena adicionar via npm uma lib como "react-leaft" que utiliza leaftlet como componentes react.

Top comments (0)