2

I am using the LeafletJS plugin to display a full page map in a ReactJS single page app. I followed the instructions here. However, the tiles are not displayed in correct order. They are ordered randomly (?). I found a similar problem here but in that case the order was fixed on page refresh. That is not true for me. My code is (excluding boilerplate):

index.html

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="stylesheets/atlas.css">
  </head>
  <body>
    <div id="app">
      Loading...
    </div>
    <script src="javascripts/atlas.js"></script>
  </body>
</html>

index.js

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('app')
)

App.jsx

import LiveMap from './LiveMap';
// App component
const App = () => (
    <LiveMap />
)
export default App;

LiveMap.jsx

class LiveMap extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div id='map'></div>
        );
    }

    componentDidMount() {
        let _map = this.map = L.map(ReactDOM.findDOMNode(this)).setView([-41.2858, 174.78682], 14);
        L.tileLayer(
            'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> Contributors',
            maxZoom: 18,
            }).addTo(_map);    
    }

    componentWillUnmount() {...}

    shouldComponentUpdate() {return false;}
};
export default LiveMap;
7
  • Try setting a timeout before you render the map. componentDidMount can be somewhat misleading in that the element has been inserted into the DOM but not fully rendered (no width and height). Leaflet needs the width and height to render properly... Commented Apr 9, 2016 at 16:03
  • What are your atlas.css and atlas.js files made of? The shuffled tiles is usually a symptom of not loading leaflet.css stylesheet.
    – ghybs
    Commented Apr 9, 2016 at 17:10
  • @SkipJack tried that. Didn't help.
    – 341008
    Commented Apr 10, 2016 at 17:54
  • @ghybs I tried loading leaflet.css explicitly. Still no success.
    – 341008
    Commented Apr 10, 2016 at 17:54
  • @341008 if it's not either of those things then I'm kind of at a loss.. Can you add a live example of the issue? Commented Apr 10, 2016 at 18:24

1 Answer 1

1

I'm pretty sure your issue is that the element has not fully rendered by the time your code executes or, as mentioned by @ghybs, not loading the Leaflet stylesheet. See this question, especially the second answer, which addresses this problem:

One drawback of using componentDidUpdate, or componentDidMount is that they are actually executed before the dom elements are done being drawn, but after they've been passed from React to the browser's DOM.

Solution

In order to get around this you must wrap your map creation code in a setTimeout like so:

componentDidMount() {
    let element = ReactDOM.findDOMNode(this)

    setTimeout(() => {
      this.map = new L.map(element, {
          center: new L.LatLng(41.019829, 28.989864),
          zoom: 14,
          maxZoom: 18,
          layers: new L.TileLayer('...')
      }, 100)
    })
  }

I put together a pen which illustrates a working example of a leaflet map inside a React component. Also make sure you are including leaflet's stylesheet:

...
<head>
  <link rel="stylesheet" href="stylesheets/atlas.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css">
</head>
...

I would also recommend using ref which I updated the pen to use. You can read more refs here.

Related Questions

Good way to combine React and Leaflet

React after render

3
  • What you are saying definitely makes sense. And your pen obviously works. But when I try doing the same in my code it breaks. I just copied code from your pen to my (stripped down) files and got shuffled tiles as before. I must be missing something basic here.
    – 341008
    Commented Apr 10, 2016 at 17:56
  • I also tried the trick with window.requestAnimationFrame(callback) mentioned in the link you pointed to. No luck.
    – 341008
    Commented Apr 10, 2016 at 18:02
  • 2
    @341008 You're most likely missing the stylesheet then.. If you look at the codepen style settings I'm loading it there (not directly through the html section) Commented Apr 10, 2016 at 18:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.