Mapbox-gl-js: ReactJs - map size issue at first load (until I resize the screen)

Created on 17 Nov 2019  Â·  7Comments  Â·  Source: mapbox/mapbox-gl-js

Hi !

I saw another question related to my issue but it didn't solve it (maybe because my react approach is wrong, I don't know...)

I have this component:

import * as React from 'react';
import {Location} from "app/models/location";
// @ts-ignore
import * as style from './style.css'
import mapboxgl, {LngLat} from "mapbox-gl";

export interface LocationMapboxProps {
    locations: Location[];
}

export interface LocationMapboxState {
    lng: number;
    lat: number;
    zoom: number
    selectedLocation: Location
}

const mapboxStyleUrl = "----";
mapboxgl.accessToken = "my-token";

export class LocationMapbox extends React.Component<LocationMapboxProps, LocationMapboxState> {
    mapContainer: HTMLDivElement = null;

    constructor(props: LocationMapboxProps, context: any) {
        super(props, context);
        this.state = {
            lng: 5,
            lat: 34,
            zoom: 2,
            selectedPlace: null
        };
    }

    componentDidMount() {
        let map = new mapboxgl.Map({
            container: this.mapContainer,
            style: mapboxStyleUrl,
            center: [this.state.lng, this.state.lat],
            zoom: this.state.zoom,
        });

        map.on('move', () => {
            this.setState({
                lng: parseFloat(map.getCenter().lng.toFixed(4)),
                lat: parseFloat(map.getCenter().lat.toFixed(4)),
                zoom: parseFloat(map.getZoom().toFixed(2))
            });
        });

        this.props.locations.map(function(location) {
            console.log(location);

            // create a HTML element for each feature
            let el = document.createElement('div');
            el.className = style["marker"];

            el.onclick = () => {
                map.flyTo({
                    center: new LngLat(location.longitude, location.latitude),
                    zoom: 15,
                    speed: .75
                });
            };

            // make a marker for each feature and add to the map
            new mapboxgl.Marker(el, {
                    anchor: "bottom"
                })
                .setLngLat(new LngLat(location.longitude,location.latitude))
                .addTo(map);
        });
    }

    render() {
        return (
            <div className={style["container"]}>
                <div className={`${style["sidebarStyle"]}`}>
                    <div>Longitude: {this.state.lng} | Latitude: {this.state.lat} | Zoom: {this.state.zoom}</div>
                </div>
                <div ref={el => this.mapContainer = el} className={style["container"]}/>
            </div>
        )
    }
}

export default LocationMapbox

and its css:

.container {
    height: 100%;
    width: 100%;
}

.sidebarStyle {
    display: inline-block;
    position: absolute;
    top: 0;
    left: 0;
    margin: 12px;
    background-color: #404040;
    color: #ffffff;
    z-index: 1 !important;
    padding: 6px;
    font-weight: bold;
}

.marker {
    background-image: url('../../../assets/pins/green.png');
    background-size: cover;
    background-color: red;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    cursor: pointer;
    border: 1px solid gray;
    offset-anchor: top;
}

THE ISSUE

While using my component, I want to be able to use it as full screen or in a small container (on the main view). However, in full screen, I have a weird behavior:

Screenshot 2019-11-17 at 13 36 38

RELATED QUESTION: https://github.com/mapbox/mapbox-gl-js/issues/3265

Thanks for any help

Most helpful comment

I finally found out..

this.map.once('load', () => {
    this.map.resize();
});

All 7 comments

Call map.resize() after the container element changes size programmatically.

Hey!

Can you be a bit more specific, please? I added your code by the end of componentDidMount and I still have the same behavior.

Thanks,

If it's still the same behavior, it means the map container didn't change the size at this moment. The reason I'm not more specific is that this is not a GL JS issue — you use the repo to get help with your application, and this is not a good place to do this. For React questions, I would suggest StackOverflow.

Alright thank @mourner for your feedback, I will then get on SO and if I find any solution, I will post it here

I finally found out..

this.map.once('load', () => {
    this.map.resize();
});

For react version:

import React from 'react';
import ReactMapboxGl, {Marker} from 'react-mapbox-gl';
import * as MapboxGl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';

export const MapBox = React.memo(function MapBox() {

    const Map = ReactMapboxGl({
        accessToken: 'Token',
        trackResize: true,

    });

    const onLoaded =(map: MapboxGl.Map) =>{
        map.resize();
    }

    return (
        <div className="main-map-container" style={{height: "100%"}}>
            <Map
                style="mapbox://styles/mapbox/streets-v9"
                containerStyle={{
                    height: "calc(100vh - 130px)",
                    width: "100%"
                }}
                center={[19.9449799, 50.06465]}
                zoom={[13]}

                onStyleLoad={(map)=>onLoaded(map)}
                onClick={()=>alert("click")}
            >
                <Marker coordinates={[19.9449799, 50.0646501]} anchor="bottom">
                    <div >test</div>
                </Marker>
            </Map>
        </div>
    );
});
map.on('idle',function(){
map.resize()
})

try this. it works fine for me.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shotor picture shotor  Â·  3Comments

BernhardRode picture BernhardRode  Â·  3Comments

iamdenny picture iamdenny  Â·  3Comments

rasagy picture rasagy  Â·  3Comments

aendrew picture aendrew  Â·  3Comments