SomethingsGottaGive
SomethingsGottaGive

Reputation: 1894

Leaflet map partially loading within React project

I am trying to implement a simple Leaflet map within a react component. For some reason the tiles of the map are not loading or loading in random order. Has anyone else experienced this?

Here's the CodeSandbox of the app: https://codesandbox.io/s/3qmp8x4131

Here's the code:

import React from "react";
import ReactDOM from "react-dom";
import * as L from "leaflet";

export default class Map extends React.Component {
  map = null;
  componentDidMount() {
    var map = (this.map = L.map(ReactDOM.findDOMNode(this), {
      minZoom: 2,
      maxZoom: 20,
      layers: [
        L.tileLayer("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
          attribution:
            '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
        })
      ],
      attributionControl: false
    }));

    map.on("click", this.onMapClick);
    map.fitWorld();
  }

  componentWillUnmount() {
    if (!this.map) return;
    this.map.off("click", this.onMapClick);
    this.map = null;
  }

  onMapClick = () => {
    // Do some wonderful map things...
  };

  render() {
    return <div className="map" />;
  }
}

Any ideas?

Upvotes: 3

Views: 2407

Answers (1)

ghybs
ghybs

Reputation: 53205

  1. You did forget to include Leaflet CSS file.
  2. You incorrectly specify your .map container height.

1. Include Leaflet CSS

Pay attention to how the working example you mention in your comment imports Leaflet assets (in Map/leaflet.js file):

import L from 'leaflet'; // Same as `import * as L from 'leaflet'` with webpack
import 'leaflet/dist/leaflet.css';

Notice that it imports Leaflet CSS file explicitly. When it is missing, your tiles will appear shuffled and spread over your page.

Webpack has a style-loader and css-loader to correctly manage these CSS assets when they are referred to in a JS file.

2. Specify the map container height

In your failing code sample, you specify your <div class="map"> container with CSS:

.map {
  height: 100%;
}

Be aware that percentage value is based on the element's parent node value, i.e. in this case 100% of the parent's height.

Your DOM hierarchy is:

<html>
  <body>
    <div id="root">
      <div class="App">
        <div class="map">

But you have not specified any height for any of your map container's ancestors (i.e. html, body, #root and .App). Since their only child is .map, they do not have anything else to increase their size, hence they have 0 height.

And your .map's height is 100% of 0, i.e. 0.

Make sure you also specify a height value for each of these ancestors:

html,
body,
#root,
.App {
  margin: 0;
  height: 100%;
}

Or use an explicit height value for your map container, e.g. in px.

Updated CodeSandbox: https://codesandbox.io/s/zn89pkmn83

Upvotes: 5

Related Questions