React-leaflet geojson onEachFeature popup with custom react component
Asked Answered
K

1

8

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!

Kipkipling answered 14/3, 2020 at 13:34 Comment(0)
S
10

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

Spavined answered 14/3, 2020 at 18:48 Comment(9)
Thank you for the answer. I have already tried a solution like this but I need to fire an event from popup, e.g. to fire a modal and with this solution it does not workKipkipling
What is preventing you not to do with this approach? Can you be more clear in what you want to achieve?Spavined
I am trying to display text (name of the object) and a button ("more info") in a popup in onEachFeature function. When a button is pressed a modal is opened with more object properties.Kipkipling
I Updated the answer. Please have a lookSpavined
Thank you. This is a solution. Also I can add that in order to use <GeoJSON> it is possible to extend it and include popupContent like in <FeatureGroup> component and use the same approach you've suggested.Kipkipling
Have not checked it but sounds possible. Please accept the answer if it helped you.Spavined
hey, this was really helpful. I abstracted popup as a seperate component and want to have a form within the popup, but submitting it didnt work, i think it ignores event handling? do you know how to fix this?Witter
Thanks. You can ask it in another thread as it goes beyond the scope of this question.Spavined
@Spavined #71141382Witter

© 2022 - 2024 — McMap. All rights reserved.