Skip to content

React, leafletjs (or any other external library) and DOM #4068

Closed
@afilp

Description

@afilp

Hello, I am trying to use React with the leafletjs library for maps and I am not sure how to implement this best.

I know that there is a react-leaflet github project out there, but in my case I need to use the raw (javaScript) leafletjs library (in order to use more unsupported features, such as the divIcon that supports html on the Marker: http://leafletjs.com/reference.html#divicon)

The following code that I wrote is definitely not the React way (as it removes and unmounts everything and then recreates and mounts everything) but it works (after many hours of trial and error).

I have around 300 Markers (cars) on the map and with different criteria I hide some of them. I also retrieve slightly updated data from the server.

The problem is that before I use the unmountComponentAtNode method, the React devtools showed that 300 components were added on each rerender. So, I had 3000 components at some time and growing, despite their underlying (real DOM) DIVs where deleted by the window.map.carsLayerGroup.clearLayers(); method.

So:

  1. Shouldn't the removal of the DOM "DIVs" (by an external library) also automatically "unmount" the related mounted components? Is there a way to do so?
  2. If not, is there a way to unmount all 300+ Car components alltogether without looping? For example, something like React.unmountComponents("Car"). Because my loop is not full-proof: when I retrieve new data, some old items will still remain mounted because they do not appear in the new list that will be looped for unmounting.
  3. Any ideas on how to approach this? The (non-react) DOM DIV per Marker needs to exist, so I need to find a way for the React component to be rendered there and use the React lifecycles without having to unmount it and recreate it on every rerender.

Thank you!

 componentWillUpdate() {

    const {props, state} = this;
    const {cars} = props;


    cars.map((car,i) => {     //Clean the previous React components
      try {
        React.unmountComponentAtNode(document.getElementById(`s${car.id}`));
      }
      catch (e) {
        //do nothing, continue execution
      }});

      window.map.carsLayerGroup.clearLayers();

      cars.map((car,i) => {
         var myIcon = L.divIcon({
          //className: '',
          iconSize: [24, 24],
          html: `<div id="s${car.id}"></div>`,
        });
        var ang = 45;
        var lat = car.lat+0.02220,
            lon =  car.lon+0.02220;
        var marker = L.marker([lat, lon], {icon: myIcon});
        window.map.carsLayerGroup.addLayer(marker);

        if (myData.filters[`checkCarsOfType${car.type}`])
          React.render(<Car key={car.id} car={car} carIndex={i} {...props}/>,document.getElementById(`${car.id}`));
      });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions