14

我有一个简单的组件来选择地图上的点,然后显示一些与该点相关的 GeoJSON 数据:

import React, { Component } from 'react';

import { Map, Marker, TileLayer, GeoJSON } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';

import { connect } from 'react-redux';
import './style.css';

import { setPoint, fetchData } from '../../actions/map';

@connect(store => {
  return {
    map: store.map
  }
})
class MyMap extends Component {

  mapClick(e) {
    this.props.dispatch(setPoint(e.latlng));
    this.props.dispatch(fetchData(e.latlng));
  }

  render() {
    const marker = () => {
      if(this.props.map.point) {
        return <Marker position={this.props.map.point} />;
      }
    };

    const data = () => {
        if(this.props.map.data.length > 0) {
            const json = this.props.map.data;
            return <GeoJSON data={json} />
        }
    }

    return (
      <div className='my-map'>
        <div className='my-map__map-container'>
          <Map center={this.props.map.center} zoom={13} onClick={this.mapClick.bind(this)}>
            <TileLayer url='http://{s}.tile.osm.org/{z}/{x}/{y}.png' attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' />
            {marker()}
            {data()}
          </Map>
        </div>
        <div className='my-map__debug'>
            {JSON.stringify(this.props.map)}
        </div>
      </div>
    );
  }
}

export default MyMap;

第一次然后我点击地图标记出现,经过一些延迟(XHR 请求)GeoJSON 呈现。但是下次我点击地图时,我只更改了标记位置,但旧的 GeoJSON 数据仍保留在地图上。调试部分组件正确呈现,并显示正确的数据。如何强制react-leaflet重新渲染我的 GeoJSON 数据,或者我做错了什么?

升级版:

在询问作者后,react-leafet我发现了如何达到预期的行为。

为了强制响应重新渲染我的 GeoJSON 数据,我需要将一些 data-uniq 键传递给组件:

<GeoJSON key={keyFunction(this.props.map.data.json)} data={this.props.map.data.json} />

https://github.com/PaulLeCam/react-leaflet/issues/332#issuecomment-304228071

4

3 回答 3

21

在询问作者后,react-leafet我发现了如何达到预期的行为。

为了强制响应重新渲染我的 GeoJSON 数据,我需要将一些 data-uniq 键传递给组件:

<GeoJSON key={keyFunction(this.props.map.data.json)} data={this.props.map.data.json} />

https://github.com/PaulLeCam/react-leaflet/issues/332#issuecomment-304228071

于 2017-05-27T21:22:55.210 回答
6
import hash from 'object-hash';

render() {
let blah = this.state; //or this.props or whatever
<GeoJSON
  key={hash(blah)}
  data={blah} />
于 2017-10-05T19:49:36.800 回答
1

从每次调用渲染方法时创建的函数调用标记和 geojson 不会非常高效。另外,我认为您可能需要为地图元素添加一个键,以便它们可以正确地重用和更新。

试试这个:

render() {

    return (
      <div className='my-map'>
        <div className='my-map__map-container'>
          <Map center={this.props.map.center} zoom={13} onClick={this.mapClick.bind(this)}>
            <TileLayer url='http://{s}.tile.osm.org/{z}/{x}/{y}.png' attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' />
            {this.props.map.point &&
              <Marker key='my-marker' position={this.props.map.point} />
            }
            {this.props.map.data.length > 0 && 
              <GeoJSON key='my-geojson' data={this.props.map.data.json} />
            }
          </Map>
        </div>
        <div className='my-map__debug'>
            {JSON.stringify(this.props.map)}
        </div>
      </div>
    );
  }
于 2017-05-25T01:11:51.523 回答