将 LeafletJS 与 ReactJS 一起使用时,Tiles 未正确排序

Posted

技术标签:

【中文标题】将 LeafletJS 与 ReactJS 一起使用时,Tiles 未正确排序【英文标题】:Tiles not ordered correctly when using LeafletJS with ReactJS 【发布时间】: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 如果不是这两件事,那我有点不知所措..你能添加一个这个问题的活生生的例子吗? 【参考方案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 部分)

以上是关于将 LeafletJS 与 ReactJS 一起使用时,Tiles 未正确排序的主要内容,如果未能解决你的问题,请参考以下文章

将 ReactJS 与 PHP 和 Laravel 一起使用 [关闭]

如何将 json 服务器与 reactjs 一起使用?

如何将 localStorage 与 apollo-client 和 reactjs 一起使用?

我应该将StencilJS与ReactJS一起使用吗?

将 Postman 与 ReactJS 和 MongooseDB 一起使用时显示“错误:套接字挂起”错误

如何通过 Express JS 服务器使 React JS 和 Socket IO 连接在一起?