3

I'm trying to use Leaflet in my React App. I'm running into an issue. Leaflet.js requires the div component to pre-exist when initiating the map. React doesn't "create" the div until it renders the component, so leaflet is throwing an error. Both getDOMNode() and findDOMNode() return "not a function" for whatever reason.

Code:

import React from 'react';
import {render} from 'react-dom';
import L from 'leaflet';

...a little later

export default class Mapbox extends React.Component {
  render() {
    var map = L.map('map').setView([51.505, -0.09], 13);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

    return (

      <div id="map">
    <h1>hi</h1>
    </div>
    );

This returns an error that "Map Container not Found".

Thanks.

4 Answers 4

4

You can initialize map inside componentDidMount

class Mapbox extends React.Component {
  componentDidMount() {
    this.map();
  }

  map() {
    var map = L.map('map').setView([51.505, -0.09], 13);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);
  }

  render() {
    return <div id="map">xx</div>  
  }
}

Example

Sign up to request clarification or add additional context in comments.

1 Comment

Oh my days it WORKS, the only thing I changed was adding a height to the div to get it to show up return <div id="map" style={{height: '200px'}}>xx</div>
4

The other answers are great if you're using class components. If you have to use it with functional components (using Hooks) than you might need to code useRef.

function Map({}) {
  // define the ref here
  const mapRef = useRef(null);

  useEffect( () => {
// set the initialized map to the ref
    mapRef.current = L.map('map').setView([51.505, 3], 13);
    
    }, []);

// pass it in the required div node
  return (
    <div ref={mapRef} id="map" className="p-2">
    </div>
  );

}

In this way the map will be initialized after the DOM node is rendered.

Reference: React hooks.

Comments

1

Since react 16.3 there is a new method for creating references easily.

note:the references can be stored in constructor as the refernces can be created prior to the jsx div is created.

class Map extends React.Component {


  componentDidMount() {
   this.map = React.createRef();
   var map = L.map(this.map).setView([51.505, -0.09], 13);
  }

  render() {
    return <div ref={this.map}></div>
  }
}

Comments

0

Use "refs". Refs is used to return a reference to the element. docs here

class Map extends React.Component {

  componentDidMount() {
    const node = this.node;
    var map = var map = L.map(node).setView([51.505, -0.09], 13);
  }

  render() {
    return <div ref={(node) => { this.node = node }}></div>
  }
}

1 Comment

I think React.createRef() is the way to go. The old callback refs isn’t recommended.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.