【问题标题】:Tiles not ordered correctly when using LeafletJS with ReactJS将 LeafletJS 与 ReactJS 一起使用时,Tiles 未正确排序
【发布时间】:2016-07-30 15:55:26
【问题描述】:

我正在使用LeafletJS 插件在ReactJS 单页应用程序中显示整页地图。我遵循了here 的指示。但是,图块的显示顺序不正确。它们是随机排序的(?)。我发现了一个类似的问题here,但在这种情况下,订单在页面刷新时是固定的。这对我来说不是真的。我的代码是(不包括样板代码):

index.html

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="stylesheets/atlas.css">
  </head>
  <body>
    <div id="app">
      Loading...
    </div>
    <script src="javascripts/atlas.js"></script>
  </body>
</html>

index.js

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('app')
)

App.jsx

import LiveMap from './LiveMap';
// App component
const App = () => (
    <LiveMap />
)
export default App;

LiveMap.jsx

class LiveMap extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div id='map'></div>
        );
    }

    componentDidMount() {
        let _map = this.map = L.map(ReactDOM.findDOMNode(this)).setView([-41.2858, 174.78682], 14);
        L.tileLayer(
            'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> Contributors',
            maxZoom: 18,
            }).addTo(_map);    
    }

    componentWillUnmount() {...}

    shouldComponentUpdate() {return false;}
};
export default LiveMap;

【问题讨论】:

  • 在渲染地图之前尝试设置超时。 componentDidMount 可能会有些误导,因为元素已插入 DOM 但未完全呈现(没有宽度和高度)。 Leaflet 需要宽度和高度才能正确渲染...
  • 您的atlas.cssatlas.js 文件是由什么组成的?打乱的磁贴通常是未加载 leaflet.css 样式表的症状。
  • @SkipJack 试过了。没有帮助。
  • @ghybs 我尝试显式加载leaflet.css。还是没有成功。
  • @341008 如果不是这两件事,那我有点不知所措..你能添加一个这个问题的活生生的例子吗?

标签: javascript reactjs ecmascript-6 leaflet


【解决方案1】:

我很确定您的问题是在您的代码执行时该元素尚未完全呈现,或者如@ghybs 所述,未加载Leaflet stylesheet。请参阅this question,尤其是第二个答案,它解决了这个问题:

使用 componentDidUpdate 或 componentDidMount 的一个缺点是它们实际上是在绘制 dom 元素之前执行,但在它们从 React 传递到浏览器的 DOM 之后。

解决方案

为了解决这个问题,您必须将地图创建代码包装在 setTimeout 中,如下所示:

componentDidMount() {
    let element = ReactDOM.findDOMNode(this)

    setTimeout(() => {
      this.map = new L.map(element, {
          center: new L.LatLng(41.019829, 28.989864),
          zoom: 14,
          maxZoom: 18,
          layers: new L.TileLayer('...')
      }, 100)
    })
  }

我整理了一个pen,它说明了 React 组件中传单映射的工作示例。还要确保您包含传单的样式表:

...
<head>
  <link rel="stylesheet" href="stylesheets/atlas.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css">
</head>
...

我还建议使用ref,我更新了pen 以使用它。您可以阅读更多参考文献here

相关问题

Good way to combine React and Leaflet

React after render

【讨论】:

  • 你说的绝对有道理。你的笔显然有效。但是当我尝试在我的代码中做同样的事情时,它会中断。我刚刚将代码从你的笔复制到我的(精简的)文件中,并像以前一样洗牌。我一定在这里遗漏了一些基本的东西。
  • 我还尝试了您指向的链接中提到的window.requestAnimationFrame(callback) 的技巧。没有运气。
  • @341008 你很可能错过了样式表。如果你查看我正在加载的 codepen 样式设置(不是直接通过 html 部分)
猜你喜欢
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 2017-08-06
  • 2015-03-13
  • 2023-04-09
  • 1970-01-01
相关资源
最近更新 更多