Search code examples
reactjsleafletpopupgeojsonreact-leaflet

React-leaflet geojson onEachFeature popup with custom react component


I am trying to render custom react component in react-leaflet GeoJSON onEachFeature popup, e.g. to fire modal with all corresponding feature.properties. In a popup react-leaflet component it works great

<Popup>
   Some text
   <Another React Component />
</Popup>

But onEachFeature function for GeoJSON looks like this

onEachFeature(feature, layer) {
    const popupContent = `
        <div>
            <p>${feature.properties.name}</p>                  
        </div>
            `;
        layer.bindPopup(popupContent);
        }

popupContent is a html code and I do not know how to include react component in it. Need help! Thank you!


Solution

  • You can use ReactDOMServer.renderToString, see here to be able to have a custom Popup component and render it using layer.bindPopup by passing feature as prop or whatever other prop you want.

    Create a Popup component like for instance:

    const Popup = ({ feature }) => {
      let popupContent;
      if (feature.properties && feature.properties.popupContent) {
        popupContent = feature.properties.popupContent;
      }
    
      return (
        <div>
          <p>{`I started out as a GeoJSON  ${
            feature.geometry.type
          }, but now I'm a Leaflet vector!`}</p>
          {popupContent}
        </div>
      );
    };
    

    And then use it inside onEachFeature along with ReactDOMServer.renderToString

    const onEachFeature = (feature, layer) => {
        const popupContent = ReactDOMServer.renderToString(
          <Popup feature={feature} />
        );
        layer.bindPopup(popupContent);
      };
    

    Edit After giving more information I changed the code to be like this:

    1. create a modal just for the sake of the example and pass as props its state, a toggle function and the selectedfeature.

    2. iterate over the geojson and create a FeatureGroup react-leaflet component, instead of using GeoJSON and listen to onEachFeature event, by passing as children react-leaflet's Popup component. Inside there you could have your button with the desired onClick event. With this ways the problem with the static html can be overcome. A marker is created and then click the button and enable the modal. Once you click the button you save the selected feature reference.

    3. If you want to extend the example to cover all possible geometry types you could check the geometry property and based on that render circle or another element.

    I updated also the demo. I hope this can help you more now.

    Demo