如何引用 react-leaflet 组件的传单层?

How to reference the leaflet layer of a react-leaflet component?

我使用 react-leaflet 在地图上可视化了一条很长的路径。用户可以从列表中 select,我希望 selected 路径有不同的颜色。再次更改状态和渲染太慢了,我正在寻找更快的解决方案。

传单路径元素有 setStyle() 方法,所以我的第一个想法是使用它而不是再次渲染。但是如何引用leaflet层呢?

class MyPathComponent extends React.Component {

  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.selected){
      this.setState({selected: true});
      LEAFLET_POLYLINE.setStyle({
        color: 'red'
      });
    }
    return false;
  }

  render() {
    return(
      <Polyline polylines={this.props.path} />
    );
  }
}

那么我应该写什么来代替这段代码中的LEAFLET_POLYLINE

react-leaflet 中的组件有一个名为 leafletElement 的 属性。我相信你可以这样做:

class MyPathComponent extends React.Component {

  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.selected){
      this.setState({selected: true});
      this.refs.polyline.leafletElement.setStyle({
        color: 'red'
      });
    }
    return false;
  }

  render() {
    return(
      <Polyline ref="polyline" polylines={this.props.path} />
    );
  }
}

注意两点:

  1. 我还没有测试过这段代码,所以它可能需要一些小的调整。
  2. 对 "ref" 使用字符串在 React 中被认为是遗留问题,因此您可能想要做一些稍微不同的事情(参见 here)。 leafletElement 是这里的重要部分。

代替上面的代码,最好只为您的自定义组件扩展 Polyline 组件(有限的文档 here):

import { Polyline } from 'react-leaflet';

class MyPathComponent extends Polyline {

  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.selected){
      this.setState({selected: true});
      this.leafletElement.setStyle({
        color: 'red'
      });
    }
    return false;
  }
}

让我知道这是否适合您。

使用 React 回调引用并添加到上面@Eric 的回答中的完整示例:

export default class MyMap extends Component {

  leafletMap = null;

  componentDidMount() {
    console.debug(this.leafletMap);
  }

  setLeafletMapRef = map => (this.leafletMap = map && map.leafletElement);

  render() {
    return (
      <Map
        ref={this.setLeafletMapRef}
      >
        <TileLayer
          attribution="Powered by <a href=&quot;https://www.esri.com&quot;>Esri</a>"
          url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
        />
      </Map>
    );
  }
}