Search code examples
reactjsreact-map-gl

react-map-gl Style Uncaught Error: Style is not done loading


I am using React-MAP-GL, and I the problem Style is not done loading, when trying to update the mapStyle object.

import React from 'react';
import ReactMapGL from 'react-map-gl';
import {defaultMapStyle, dataLayer} from './map-style.js';

import {fromJS} from 'immutable';
import geoJson from './cali.json';

export default class Map extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      mapStyle: defaultMapStyle,
      data: null,
      viewport: {
        width: 600,
        height: 800,
        latitude: 36.7783,
        longitude: -119.4179,
        zoom: 5,
      },
    };
  }

  componentDidMount() {
    window.addEventListener('resize', this._resize);
    this._loadData(geoJson);
  }


  _loadData = data => {
    const mapStyle = defaultMapStyle
      .setIn(['sources', 'incomeByState'], fromJS({type: 'geojson', data}))
      .set('layers', defaultMapStyle.get('layers').push(dataLayer));

    this.setState({data, mapStyle});
  };

  render() {
    return (
      <div>
        <ReactMapGL
          {...this.state.viewport}
          mapStyle={this.state.mapStyle}
          onViewportChange={viewport => {
            this.setState({viewport});
          }}
          mapboxApiAccessToken=""
        />
      </div>
    );
  }
}

Solution

  • The example on react-map-gl didn't work for me, and this is what they did. I think their method is working only because requestJson has this._loadData on a callback, but I am preloading the geojson.

    componentDidMount() {
        window.addEventListener('resize', this._resize);
        this._resize();
    
        requestJson('data/us-income.geojson', (error, response) => {
          if (!error) {
            this._loadData(response);
          }
        });
      }
    

    But I did found a few ways of fixing it:

    Option #1:

    setTimeout(() => this._loadData(geoJson), 1); Even 1 milli-second solves the problem with original approach.

    Option #2: Do not load the data using ComponentDidMount, just put a onClick, or 'onScroll' event somewhere else to load the data. Kind of hacky...

    Option #3: Use onLoad! For some reason, I did not find this method in the first place...

    <MapGL
              ref={map => (this.mapRef = map)}
              {...this.state.viewport}
              mapStyle={this.state.mapStyle}
              onLoad={() => this._loadData(geoJson)}
              onViewportChange={viewport => {
                this.setState({viewport});
              }}
              mapboxApiAccessToken="8jiOnPbYA"
            />