Description
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:
- 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?
- 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.
- 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}`));
});