Dynamically create contents for a popup in react-leaflet due to many markers

Viewed 22

In order to save loading time, I don't want that text of each popup belonging to a marker is loaded initially. Instead I would like the contents to be loaded when the users clicks on the marker. So far I haven't found a way to load the contents separately. When opening the map all markers are loaded and so is the popup contents. My code so far looks as follows:

function SingleMarker (props) {

    let row = props.row;
    let site_id = props.row[0]

    const [popupContents, setPopupContents] = useState("")

    useEffect(() => {
        axios.get(`/api/site?site_id=${site_id}`)
            .then(res => {
                setPopupContents(`id: ` + res.data['site_id'])
            })
            .catch(error => {
                console.error('There was an error', error)
            })

    });


    const onOpen = React.useCallback(() => () => {}, []);

    return (
        <Marker position={[row[2], row[1]]} onOpen={onOpen}>
            <Popup>
                {popupContents}
            </Popup>
        </Marker>
    )


}

export default SingleMarker; 

I took the useCallback function from this example https://codepen.io/ulken/pen/JjJWKNM that was linked here: https://github.com/PaulLeCam/react-leaflet/issues/895

I also saw this SO question, but it seems the author is trying to load all data for the relevant markers at once, while I would like to load only for a single marker popup. React Leaflet - Dynamically load popup content

If anybody has other suggestions on how to improve load time for text being shown in the marker popups, I would also be happy about answers. By the way, I am also using react-leaflet-markercluster

1 Answers

Can you add ',[]' to your useEffect to look like this :

  useEffect(() => {
        axios.get(`/api/site?site_id=${site_id}`)
            .then(res => {
                setPopupContents(`id: ` + res.data['site_id'])
            })
            .catch(error => {
                console.error('There was an error', error)
            })

    },[]);

And then whenever you click on any marker, you can use the callback, to fire the corresponding API to fetch the data.

Related