Reputation: 1812
I am using leaflet in my react code and I am not using react-leaflet. I want to pass a react component or jsx code to binbPopup function to every tooltip.
let marker = new L.marker(...).bindPopup(<div>Hi</div>)
bindPopup gets string as a input so I cannot use jsx. I also tried to use react portals but still it doesn't work. What is the solution for this problem?
Upvotes: 8
Views: 4620
Reputation: 513
Using ReactDOMServer.renderToString()
in the client side is not recommended, as it significantly increases the app bundle size, see React docs.
Therefore, the best way to get the HTML string equivalent of a component is:
use
createRoot
and read HTML from the DOM
import { createRoot } from "react-dom/client";
import { flushSync } from "react-dom";
const popup = (<div>...</div>);
let marker = new L.marker(...).bindPopup(() => {
const div = document.createElement("div");
const root = createRoot(div);
flushSync(() => {
root.render(popup);
});
return div.innerHTML;
});
Upvotes: 3
Reputation: 9733
You can use renderToString method of ReactDOMServer
to convert React component to markup string.
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 CustomReactPopup = () => {
return (
<div style={{ fontSize: "24px", color: "black" }}>
<p>A pretty React Popup</p>
</div>
);
};
class App extends Component {
componentDidMount() {
var map = L.map("map").setView([51.505, -0.09], 13);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.marker([51.5, -0.09])
.addTo(map)
.bindPopup(ReactDOMServer.renderToString(<CustomReactPopup />))
.openPopup();
}
render() {
return (
<div>
<div id="map" />
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Working example here: https://codesandbox.io/s/leaflet-with-react-znk11
Upvotes: 13