Как обновить свойства круга Mapbox при изменении состояния React?

avatar
likearohlingstone
8 апреля 2018 в 04:28
935
1
0

Я работаю над проектом React, который получает данные из двух полей выбора, запрашивает значения во внешнем файле JSON и сопоставляет результат с помощью Mapbox. Мой код структурирован как один файл без Redux, так как мне нужен довольно быстрый оборот, и я не могу понять, как использовать Redux. До сих пор я получил программу для сопоставления значений с начальным состоянием. Однако у меня возникают проблемы с обновлением карты при изменении значений в полях выбора. Код в моем классе выглядит следующим образом:

class VID extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.handleChange = this.handleChange.bind(this);

    this.state = {
      //Set initial state. This works.
    };
  }

  componentDidMount(){
    const mapConfig = {
      //map configuration
    };

    mapboxgl.accessToken = 'token';

    const map = new mapboxgl.Map(mapConfig);

    //Loop through dataset. Find records meeting a criteria. Push to array. 
    //This works fine.
    var arr = [];

    Object.keys(Data).forEach(function(key) {
      if (//filtering criteria are met) {
        arr.push(Data[key]);
      };
    });

    //Define layers for each matching record. 
    Object.keys(arr).forEach(function(key) {
      map.on('load', function() {
        map.addLayer({
          "id": key,
          "type": "circle",
          "source": {
            "type": "geojson",
            "data": {
              "type": "Feature",
              "geometry": {
                "type": "Point",
                "coordinates": [arr[key].LONG, arr[key].LAT]
              },
            }
          },
          "paint": {
            'circle-radius': //formula to set radius based on count,
            'circle-color': '#000000'
          }
        });
      })
    })
  }

  //SOMEWHERE INSIDE THIS HANDLECHANGE BLOCK LIES MY PROBLEM
  handleChange(e) {
    this.setState({
      //Set state based on values of select boxes. This works.
    },
    function(){
      //Same as before. Create an array of matching records.
      var arr = [];

      Object.keys(Data).forEach(function(key) {
        if (//new filtering criteria are met) {
          arr.push(Data[key]);
        };
      });

      Object.keys(arr).forEach(function(key) {
        map.setPaintProperty(key, 'circle-radius', //formula)
      });
    })
  }

  render() {
    return (
      //All of my JSX
    )
  }

Когда я запускаю приведенный выше код, я получаю следующую ошибку в своей веб-консоли: TypeError: map.setPaintProperty не является функцией. Моя веб-страница также дает сбой (переход от показа моего пользовательского интерфейса к пустой белой странице).

Я попробовал несколько других средств:
* Используя this.map.setPaintProperty (TypeError: this is undefined)
* Пробуем другие методы жизненного цикла, такие как componentWillReceiveProps и shouldComponentUpdate (код не выполняется, когда я изменяю параметры в полях выбора — подтверждается с помощью console.log)
* Определение карты внутри класса, но вне методов жизненного цикла (сбой сборки модуля: SyntaxError: Unexpected token)
* Определение карты вне класса (Ошибка: контейнер 'map' не найден.)

Как мне структурировать код, чтобы можно было обновлять размеры кругов?

Если это поможет, я запускаю react 16.2.0 с mapbox-gl 0.44.0

Источник

Ответы (1)

avatar
likearohlingstone
11 апреля 2018 в 01:20
0

Я разобрался со своей проблемой. Этот ответ написан для потомков.

Проблема связана с масштабом. Я определил карту как константу (const map = ...), которая устанавливает переменную с локальной областью. Вместо этого определите карту без постоянного тега (map = ...). Это позволяет получить доступ к переменной карты через модули жизненного цикла.

Забавно, как маленькие вещи вызывают большие проблемы.