简体   繁体   中英

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

I used react-leaflet to visualize a quite long path on a map. Users can select from a list and I would like to have different color for the selected path. Changing the state and rendering again is too slow, I am looking for a faster solution.

Leaflet path elements have setStyle() method, so my first idea was using it instead of rendering again. But how to reference the leaflet layer?

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} />
    );
  }
}

So what should I write instead of LEAFLET_POLYLINE in this code?

Components in react-leaflet have a property called leafletElement . I believe you can do something like this:

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} />
    );
  }
}

Two things to note:

  1. I haven't tested this code, so it may need some small tweaks.
  2. Using a string for "ref" is considered legacy in React, so you'll probably want to do something slightly different (see here ). The leafletElement is the important part here.

Instead of the code above, it may be better to just extend the Polyline component for your custom component (limited docs 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;
  }
}

Let me know if any of this works out for you.

Full example using React callback ref and adding to @Eric's answer above:

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>
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM