0

I having an issue trying to resize my map using fitbounds on load.

So I can use handleClick is correctly resizing the map but when I the fitToCustomLayer never works as this.mapRef.current & this.groupRef.current are always null.

How can I get the fitbounds to trigger on load?

import React, {createRef, useRef, Component} from "react";
import {Link} from "react-router-dom";
import {MapContainer, TileLayer, Marker, Popup, FeatureGroup, useMapEvents} from "react-leaflet";
import L from "leaflet";


class Map extends Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
        this.mapRef = createRef();
        this.groupRef = createRef();
        this.locations = null;
        this.state = {
            error: null,
            isLoaded: false,
            data: null,
        };
    }

    async componentDidMount() {
        const el = document.getElementById('root')
        const url = el.dataset.baseurl + 'maps/display/' + el.dataset.mapid;

        try {
            fetch(url)
                .then(res => res.json())
                .then(
                    (result) => {
                        if (result.success) {
                            this.setState({
                                isLoaded: true,
                                data: result.data,
                            });
                        }
                    },
                    // Note: it's important to handle errors here
                    // instead of a catch() block so that we don't swallow
                    // exceptions from actual bugs in components.
                    (error) => {
                        this.setState({
                            isLoaded: true,
                            error
                        });
                    }
                )
        } catch (err) {
            console.log('error',err);
        }

        //let mapInst = this.mapRef.current.leafletElement;
        //const group = this.groupRef.current.leafletElement; //get native featureGroup instance
        //mapInst.fitBounds(group.getBounds());
        //const map = useMap();
    }

    createMarkers() {
        const {data} = this.state;

        this.locations = Object.values(data.locations)

        return this.locations.map(function (item) {
            return (
                <Marker key={item.id} position={[item.map.lat, item.map.lng]}>
                    <Popup>
                        <h4>{item.name} 1</h4>
                    </Popup>
                </Marker>
            )
        })
    }

    handleClick() {
        let map = this.mapRef.current;
        let group = this.groupRef.current;
        map.fitBounds(group.getBounds());
    }

    fitToCustomLayer() {
        if (this.mapRef.current && this.groupRef.current) { //we will get inside just once when loading
            const map = this.mapRef.current
            const group = this.groupRef.current
            map.fitBounds(group.getBounds().pad(0.5))
        }
    }

    render() {
        const {error, isLoaded, data} = this.state;

        if (error) {
            return (
                <div>Error: {error.message}</div>
            );
        } else if (!isLoaded) {
            return (
                <div>Loading...</div>
            );
        } else {
            let locations = Object.values(data.locations);

            return (
                <div>
                    <button onClick={this.handleClick}>Zoom</button>
                    <MapContainer ref={this.mapRef} center={[data.lat, data.long]}
                                  zoom={13} scrollWheelZoom={false} onlayeradd={this.fitToCustomLayer()} >
                        <TileLayer
                            attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                        />
                        <FeatureGroup ref={this.groupRef}>
                            {this.createMarkers()}
                        </FeatureGroup>
                    </MapContainer>
                    <ul>
                        {locations.map((item, idx) => (
                            <li key={item.id}>
                                {item.name}
                                <Link to={"location/" + item.slug}>Details</Link>
                            </li>
                        ))}
                    </ul>
                </div>
            );

        }
    }
}

export default Map;
Chris Croft
  • 13
  • 1
  • 4

0 Answers0