【问题标题】:Good way to combine React and Leaflet结合 React 和 Leaflet 的好方法
【发布时间】:2015-01-01 12:43:08
【问题描述】:

我正在做一个结合 React 和 Leaflet 的项目,但我必须说我在语义方面遇到了一些困难。

由于大部分东西都是由 Leaflet 直接管理的,我不知道将 Leaflet 映射实例添加为 React 组件中的状态是否有意义。

在使用 Leaflet 创建标记时遇到同样的问题,因为它不返回任何内容,我没有任何东西可以渲染。逻辑本身对我来说似乎很模糊。

这是我开始制作的。它可以工作,但我觉得我在编写糟糕的代码并且错过了这个概念。

/** @jsx React.DOM */

/* DOING ALL THE REQUIRE */
var Utils = require('../core/utils.js');

var Livemap = React.createClass({
    uid: function() {
        var uid = 0;
        return function(){
            return uid++;
        };
    },
    getInitialState: function() {
        return {
            uid: this.uid()
        }
    },
    componentDidMount: function() {
        var map = L.map('map-' + this.state.uid, {
            minZoom: 2,
            maxZoom: 20,
            layers: [L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'})],
            attributionControl: false,
        });
        map.fitWorld();
        return this.setState({
            map: map
        });
    },
    render: function() {
        return (
            <div className='map' id={'map-'+this.state.uid}></div>
        );
    }
});

(function(){
    Utils.documentReady(function(){
        React.render(
            <Livemap />,
            document.body
        )
    });
})();

所以我的问题是:

  • 这个样本看起来合法吗?
  • 您将如何处理添加标记和管理其事件的逻辑?

【问题讨论】:

    标签: javascript leaflet reactjs


    【解决方案1】:
    • 您不需要自己管理唯一性,即“UID”。相反,您可以使用getDOMNode 来访问组件的真实节点。 Leaflet 的 API 支持字符串选择器或 HTMLElement 实例。
    • Leaflet 正在管理渲染,因此map 不应存在于state 上。仅将数据存储在state 中,这会影响 React 对 DOM 元素的渲染。

    除了这两点之外,请正常使用 Leaflet API,并根据需要将 React 组件的回调绑定到 Leaflet 映射。 React 在这一点上只是一个包装器。

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    class Livemap extends React.Component {
    
        componentDidMount() {
            var map = this.map = L.map(ReactDOM.findDOMNode(this), {
                minZoom: 2,
                maxZoom: 20,
                layers: [
                    L.tileLayer(
                        'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                        {attribution: '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'})
                ],
                attributionControl: false,
            });
    
            map.on('click', this.onMapClick);
            map.fitWorld();
        }
    
        componentWillUnmount() {
            this.map.off('click', this.onMapClick);
            this.map = null;
        }
    
        onMapClick = () => {
            // Do some wonderful map things...
        }
    
        render() {
            return (
                <div className='map'></div>
            );
        }
    
    }
    

    【讨论】:

    • 您好,我想知道您是否可以花时间向我解释一些有关使用 Leaflet 和 React 的内容。我想添加一些非常自定义的标记(所以我将使用带有一些 html 的 iconDiv)并想在这些元素上添加不同的事件(标记本身和标记的某些特定部分)你会怎么做?由于 ReactComponent 并没有真正返回 html。
    • @SwannPolydor,我不确定你的意思。你能打开一个新问题并发布一些代码吗?
    • 如果我错了,请纠正我,但这个解决方案会在每个 Livemap render 上构建一个新地图,不是吗?我们不应该避免这种情况吗?
    • 因为render 每次都返回相同的东西,所以 React 在第一次渲染后永远不会接触到真实的 DOM。这不会在每次重新渲染时构建新地图。为了进一步改善这一点,你可以告诉 React 永远不要按照 using React with other libraries 中的建议进行更新,方法是从 shouldComponentUpdate 返回 false
    • @GiorgiMoniava React.createClass "autobound" 在传递给它的对象上声明的函数。如果您使用createClass,则不需要单独的bind 调用。如果你使用的是 ES6 类,那你肯定是对的;你需要绑定。
    【解决方案2】:

    作为一个额外的、不太详细的答案,PaulLeCam 的 react-leaflet 组件似乎很受欢迎。还没用过,但看起来很有希望:

    https://github.com/PaulLeCam/react-leaflet

    更新:它很可靠。还没有使用很多功能,但是代码库编写得很好,易于遵循和扩展,而且我使用的功能开箱即用。

    【讨论】:

    • 你如何使用他提供的基础组件?这些是否应该在 组件之外用作单独的 React 组件?
    • @maxwell 取决于您的需求——我通常在组件树的某个位置将它们呈现在 &lt;Map&gt; 中。
    猜你喜欢
    • 1970-01-01
    • 2022-10-22
    • 2023-03-30
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 2023-01-02
    • 1970-01-01
    • 2019-10-04
    相关资源
    最近更新 更多