React-map-gl(GeoJSON 地图示例):地图中的数据未通过控制面板(年份滑块)更新

问题描述 投票:0回答:1

我正在尝试从这里实现 GeoJSON 示例:https://uber.github.io/react-map-gl/#/Examples/geo但是当我尝试逐年更改年份滑块时,数据和数据层保持不变,根本没有改变。

我复制了相同的代码并集成到我的“create-react-app”中,地图的渲染方式与示例中相同,但数据保持静态并拒绝从控制面板更改。

有人可以告诉我我错过了什么吗?

我的代码是这样的:

const MAPBOX_TOKEN =
  "pk.eyJ1IjoiZnN5bHFhIiwiYSI6ImNrNXp2enFmMzAxbDAzb21iemMxN2dqY2MifQ.TvYAgClf77WIygyRg_Sa4Q"; // Set your mapbox token here

export default class GeoApp extends Component {
  state = {
    year: 2015,
    data: null,
    hoveredFeature: null,
    viewport: {
      latitude: 40,
      longitude: -100,
      zoom: 3,
      bearing: 0,
      pitch: 0
    }
  };



  componentDidMount() {
     requestJson(
      "https://raw.githubusercontent.com/uber/react-map-gl/master/examples/.data/us-income.geojson",
      (error, response) => {
        if (!error) {
          this._loadData(response);
          console.log(response);
        }
      }
    );
  }

  _loadData = data => {
    updatePercentiles(data, f => f.properties.income[this.state.year]);
    this.setState({ data });
  };

  _updateSettings = (name, value) => {
    console.log(`name:${name}, value:${value}`);
    if (name === "year") {
      this.setState({ year: value });

      const { data } = this.state;
      if (data) {
        console.log("data before", data);
        updatePercentiles(data, f => f.properties.income[value]);
        console.log("data after", data);
        // trigger update
        this.setState({ data: { ...data } });
      }
      console.log("data", data);
    }
  };

  _onViewportChange = viewport => this.setState({ viewport });

  _onHover = event => {
    const {
      features,
      srcEvent: { offsetX, offsetY }
    } = event;
    const hoveredFeature =
      features && features.find(f => f.layer.id === "data");

    this.setState({ hoveredFeature, x: offsetX, y: offsetY });
  };

  _renderTooltip() {
    const { hoveredFeature, x, y } = this.state;

    return (
      hoveredFeature && (
        <div className="tooltipi" style={{ left: x, top: y }}>
          <div>State: {hoveredFeature.properties.name}</div>
          <div>Median Household Income: {hoveredFeature.properties.value}</div>
          <div>
            Percentile: {(hoveredFeature.properties.percentile / 8) * 100}
          </div>
        </div>
      )
    );
  }

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

    return (
      <div style={{ height: "100%" }}>
        <MapGL
          {...viewport}
          width="50%"
          height="50%"
          mapStyle="mapbox://styles/mapbox/light-v9"
          onViewportChange={this._onViewportChange}
          mapboxApiAccessToken={MAPBOX_TOKEN}
          onHover={this._onHover}
        >
          <Source type="geojson" data={data}>
            <Layer {...dataLayer} />
          </Source>
          {console.log("layers", dataLayer)}
          {this._renderTooltip()}
        </MapGL>

        <ControlPanel
          containerComponent={this.props.containerComponent}
          settings={this.state}
          onChange={this._updateSettings}
        />
      </div>
    );
  }
}
export function RenderToDom(container) {
  render(<GeoApp />, container);
}

updatePercentelies 函数是这样的:

import { range } from "d3-array";
import { scaleQuantile } from "d3-scale";

export function updatePercentiles(featureCollection, accessor) {
  const { features } = featureCollection;
  const scale = scaleQuantile()
    .domain(features.map(accessor))
    .range(range(9));
  features.forEach(f => {
    const value = accessor(f);
    f.properties.value = value;
    f.properties.percentile = scale(value);
  });
}
reactjs d3.js mapbox mapbox-gl-js react-map-gl
1个回答
0
投票

在react-map-glGitHub页面上,有人解释说

<Source>
是一个PureComponent。第一次渲染后,除非 props 发生浅层变化,否则它不会更新,即 oldValue !== newValue。当您改变 JSON 数据时,它仍然是同一个对象,因此 React 不会检测到更改。

我在尝试传递保存在 React 状态中的 geoJSON 对象时遇到了完全相同的问题。解决该问题的解决方案是设置不同的键并强制重新渲染

<Source>
组件:

import React, { useState } from 'react';
import Map, { Source } from 'react-map-gl';

const MyMap = () => {
  const [geojson, setGeojson] = useState(initialGeojson);
  const [key, setKey] = useState(0);

  // Function to update GeoJSON
  const updateGeojson = (newGeojson) => {
    setGeojson(newGeojson);
    setKey(key + 1); // Increment key to force re-render
  };

  return (
    <Map {...viewport}>
      <Source id="my-data" type="geojson" data={geojson} key={key}>
        {/* Add your layers here */}
      </Source>
    </Map>
  );
};

或者您也可以使用像

uuid
这样的包为每次重新渲染生成随机密钥。

© www.soinside.com 2019 - 2024. All rights reserved.