Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render react component in Leaflet popup.setContent()

I want to render the react component in Leaflet popup as popup.setContent(<MyCustomComponent/>).

Seems like I can set only <String|HTMLElement|Function> htmlContent.

Since, There are few user interactions in my custom component, I can't use ReactDOMServer.renderToString().

Any suggestions?

like image 222
Jerry Avatar asked Jan 22 '26 11:01

Jerry


1 Answers

You render the CustomReactPopup component in html, pass it to a marker, and then add event listeners to your component. Perhaps this is not the best solution to the problem, but so far it has been possible to solve it only in this way. codesandbox

import React, { Component } from "react";
import ReactDOM from "react-dom";
import ReactDOMServer from "react-dom/server";
import * as L from "leaflet";
import "./styles.css";

const GEO_POSITION = [51.5, 0];

const CustomReactPopup = () => {
  return (
    <div style={{ fontSize: "14px" }}>
      <p>CustomReactPopup</p>
      <button id="popup-button-id">Click</button>
    </div>
  );
};

class App extends Component {
  state = {
    center: GEO_POSITION,
    zoom: 13
  };

  clickHandler = () => {
    console.count("click");
  };

  gtt = () => {
    const buttonEl = document.getElementById("popup-button-id");

    if (buttonEl) {
      buttonEl.addEventListener("click", this.clickHandler);
    }
  };

  gtt2 = () => {
    const buttonEl = document.getElementById("popup-button-id");

    if (buttonEl) {
      buttonEl.removeEventListener("click", this.clickHandler);
    }
  };

  componentDidMount() {
    var map = L.map("map").setView(GEO_POSITION, 13);

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

    L.marker(GEO_POSITION)
      .addEventListener("popupopen", this.gtt)
      .addEventListener("popupclose", this.gtt2)
      .addTo(map)
      .bindPopup(ReactDOMServer.renderToString(<CustomReactPopup />))

      .openPopup();
  }

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

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

like image 92
Roman Karas Avatar answered Jan 25 '26 23:01

Roman Karas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!