0

我从 App 组件状态设置面板组件的属性。当我单击按钮时,我想增加(示例)地图坐标。没关系,但我必须在 Panel 的 componentDidMount() 中声明 openlayers 变量,但 componentDidMount 一旦运行,坐标不会改变地图我该怎么办?请帮忙 ... 。

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Panel from './Map'


class App extends Component {
  constructor() {
    super();
    this.state = {
      coordinates: [46.41, 40.82]
    }
  }
  render() {

    return (
      <div >
        <Panel coordinates={this.state.coordinates} />
        <div><button onClick={() => {
          this.setState({
            coordinates: [this.state.coordinates[0] + 1, this.state.coordinates[1]]
          })
        }}>Go</button></div>
      </div>
    );
  }
}

export default App;

面板组件

import React from 'react'
import 'ol/ol.css';
import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import proj from 'ol/proj/';
import { fromLonLat } from 'ol/proj';

export default class Panel extends React.Component {

    constructor() {
        super();
        this.state = {
            crd: [46, 40]
        }
    }
    GetCoordinates() {
        return this.state.crd
    }

    componentWillReceiveProps(prp) {
        this.setState({ crd: prp.coordinates })
    }
    componentDidMount() {
        const map = new Map({
            target: 'map',
            layers: [
                new TileLayer({
                    source: new OSM()
                })
            ],
            view: new View({
                center: fromLonLat(this.GetCoordinates()) // i need set here,
                zoom: 7
            })
        });
    }
    render() {
        return <div id="map" style={{ width: '700px', height: '500px' }}></div>
    }
}
4

1 回答 1

0

开放层有一个命令式 API,这意味着您必须调用地图对象上的方法来更新它。

因此,首先您需要在实例化地图时保留地图的参考componentDidMount

componentDidMount() {
    this.map = new Map({
        target: 'map',
        layers: [
            new TileLayer({
                source: new OSM()
            })
        ],
        view: new View({
            center: fromLonLat(this.GetCoordinates()) // i need set here,
            zoom: 7
        })
    });
}

然后,componentWillReceiveProps一旦您的状态发生变化,您必须“命令”地图以更新其中心:

componentWillReceiveProps(prp) {
    this.setState({ crd: prp.coordinates }, function() {
        this.map.getView().setCenter(ol.proj.fromLonLat(this.GetCoordinates()));
    });
}

请注意,此处您的组件不需要将坐标保持在其状态。您可以使用普通实例变量来存储坐标并避免由以下原因引起的不必要渲染setState

....
constructor() {
    super();
    this.crd = [46, 40];
}
GetCoordinates() {
    return this.crd
}
componentWillReceiveProps(prp) {
    this.crd = prp.coordinates;
    this.map.getView().setCenter(
        ol.proj.fromLonLat(this.GetCoordinates())
    );
}
....
于 2018-08-16T12:38:09.950 回答