如何在React的嵌套函数中设置setState()?

时间:2019-08-27 14:20:06

标签: reactjs mapbox mapbox-gl-js

我正在尝试改编https://github.com/mapbox/mapbox-react-examples/tree/master/basic中的示例,

import React from 'react'
import ReactDOM from 'react-dom'
import mapboxgl from 'mapbox-gl'

mapboxgl.accessToken = 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4M29iazA2Z2gycXA4N2pmbDZmangifQ.-g_vE53SD2WrJ6tFX7QHmA';

class Application extends React.Component {

  constructor(props: Props) {
    super(props);
    this.state = {
      lng: 5,
      lat: 34,
      zoom: 1.5
    };
  }

  componentDidMount() {
    const { lng, lat, zoom } = this.state;

    const map = new mapboxgl.Map({
      container: this.mapContainer,
      style: 'mapbox://styles/mapbox/streets-v9',
      center: [lng, lat],
      zoom
    });

    map.on('move', () => {
      const { lng, lat } = map.getCenter();

      this.setState({
        lng: lng.toFixed(4),
        lat: lat.toFixed(4),
        zoom: map.getZoom().toFixed(2)
      });
    });
  }

  render() {
    const { lng, lat, zoom } = this.state;

    return (
      <div>
        <div className="inline-block absolute top left mt12 ml12 bg-darken75 color-white z1 py6 px12 round-full txt-s txt-bold">
          <div>{`Longitude: ${lng} Latitude: ${lat} Zoom: ${zoom}`}</div>
        </div>
        <div ref={el => this.mapContainer = el} className="absolute top right left bottom" />
      </div>
    );
  }
}

ReactDOM.render(<Application />, document.getElementById('app'));

在这种情况下,我不想显示地图的中心,而是想显示鼠标位置的纬度和经度。

到目前为止,我已经成功地将其记录到控制台:

import React from 'react';
import mapboxgl from 'mapbox-gl';

mapboxgl.accessToken = 'pk.eyJ1Ijoia3VydHBlZWsiLCJhIjoiY2p6cnVneWdvMHlzeDNqcWo0dm83ZzZ2eiJ9.yUCSreTRcKs12uT5PTCztg';


export default class Map extends React.Component {
  componentDidMount() {
    this.map = new mapboxgl.Map({
      container: this.mapContainer,
      style: 'mapbox://styles/mapbox/outdoors-v11',
      center: [-119.5591, 37.715],
      zoom: 9
    });

    this.map.on('load', function(e) {    
      e.target.on('mousemove', function(e) {
        console.log(JSON.stringify(e.point));
        console.log(JSON.stringify(e.lngLat.wrap()));
      });
    });
  }

  componentWillUnmount() {
    this.map.remove();
  }

  render() {
    const style = {
      position: 'absolute',
      top: 0,
      bottom: 0,
      width: '100%'
    };

    return <div style={style} ref={el => this.mapContainer = el} />;
  }
}

这会将类似以下内容的行写入控制台:

{"x":972,"y":272}
{"lng":-118.90266689452113,"lat":37.86205552587528}

但是,我不想像在示例中那样调用this.setState(),而不是将坐标记录到控制台,以便可以在子组件中渲染坐标。

问题是在on('mousemove', ...)回调函数中,this不是组件。我已经读过使用箭头功能(在词法范围内)解决此问题的方法,但是在我看来,在这种情况下,我需要一个“普通” function(e)才能捕获事件。

在此示例中,如何setState()使用鼠标坐标?

1 个答案:

答案 0 :(得分:2)

可以像其他arrow functions一样使用function

this.map.on('load', e => {    
  e.target.on('mousemove', e => {
      this.setState({}) //correct this
  })
})