这里有一个新的react-leaflet版本,可以在这里找到: npm install react-leaflet /下一个 docs:https://react-leaflet-v3.now.sh/docs/start-introduction
使用钩子完全重写。
基于这些新的挂钩,我试图编写一个自定义的图层控件,我主要只是想将其分成几组并从material-ui渲染我的react组件,以使地图样式与我的应用程序的其余部分保持一致。根据我的理解,这些钩子像傻瓜一样被使用:
基本控制示例
const MyControl = Control.extend({
onAdd: map => {
let container = DomUtil.create('div');
container.innerHTML += 'My Control';
return container;
},
// this one is optional
onRemove: map => {},
});
const useControlElement = createElementHook(
function createControl(_ref, ctx) {
const context = useLeafletContext();
var instance = new MyControl(position);
return {
instance: instance,
context: Object.assign({}, ctx, {
control: instance,
}),
};
},
function updateControl(control, props, prevProps) {},
);
const useControl = createControlHook(useControlElement);
const FinalControl = createContainerComponent(useControl);
function ControlComponent({ children }) {
const controlRef = useRef();
// if ref exits portal children through, note: using react scripts to support ?
if(ref.?current?.getContainer()){
ReactDOM.createPortal(children, ref.current.getContainer())
}
return <FinalControl ref={controlRef} />;
}
export default ControlComponent;
但是,子控件永远不会呈现,因为控件仅添加在componentDidMount上。
我想在React / JSX / JS中编写此层控件,我不想完全使用html即L.Control并使用传单domutil来完全构建它,因为无论如何我的反应样式都无法使用,提供对我的redux存储的受限访问。因此,我试图通过基本的控件(例如react-leaflet-control的工作方式)来门户组件
我以正确的方式来处理吗?我只是绕圈自动取款机,试图使它以一种很好的方式工作。我快要把一个React组件作为地图的子级渲染并将位置设置为绝对位置了(我知道这是错误的方法,但确实可以做到)
即
<MapContainer>
<ReactComponent />
</MapContiner>
文档中有一个自定义组件的示例,但这仅适用于已经存在的传单组件,即“核心体系结构”部分中的方形示例。任何帮助表示赞赏!
答案 0 :(得分:3)
感谢扎克的回答,我可以通过这种方式做到这一点。
依赖版本:
"react-leaflet": "^3.0.5",
"leaflet": "^1.7.1",
这是一个扩展 Leaflet 控件的组件。您可以使用选项来自定义带有接收到的道具的组件。
//MyComponent.jsx
import React from 'react';
import {useLeafletContext} from '@react-leaflet/core';
import L from 'leaflet';
export const MyComponent = (props) => {
const context = useLeafletContext();
const control = L.control.Extend({
//...options
});
React.useEffect(() => {
const container = context.layerContainer || context.map;
container.addControl(control);
return () => {
container.removeControl(control);
};
});
return null;
};
这里是自定义地图组件,您可以在其中使用之前创建的组件。
//MyMapComponent.jsx
import React from 'react';
import {MapContainer, TileLayer} from 'react-leaflet';
import {MyComponent} from './MyComponent';
export const MyMapComponent = (props) => {
return (
<MapContainer>
<TileLayer url="whateverLayerURL" />
<MyComponent {...props} />
</MapContainer>
);
};
答案 1 :(得分:3)
这可以使用 createControlComponent 钩子进一步简化
import { createControlComponent } from "@react-leaflet/core";
import { Control, DomUtil } from "leaflet";
Control.Watermark = Control.extend({
onAdd: function (map) {
const img = DomUtil.create("img");
img.src = "./logo.png";
img.style.width = "200px";
return img;
},
onRemove: function (map) {},
});
export const WatermarkControl = createControlComponent(
(props) => new Control.Watermark(props)
);
答案 2 :(得分:-1)
我更新了答案。不确定是否对您有帮助,但希望它可以为您提供提示。
我从here的普通Leaflet示例中模拟了该示例,该示例在地图的左下方添加了一个控件。
import { MapContainer, TileLayer } from 'react-leaflet';
import { useLeafletContext } from '@react-leaflet/core'
import L from 'leaflet';
import {useEffect} from 'react'
function CustomControl(props) {
const context = useLeafletContext()
L.Control.Watermark = L.Control.extend({
onAdd: function (map) {
var img = L.DomUtil.create('img');
img.src = './logo.png';
img.style.width = '200px';
return img;
},
onRemove: function (map) {
// Nothing to do here
}
});
L.control.watermark = function (opts) {
return new L.Control.Watermark(opts);
}
useEffect(() => {
const container = context.layerContainer || context.map
const control = L.control.watermark({ position: props.position })
container.addControl(control)
return () => {
container.removeControl(control)
}
})
return null
}
function MapCompenent() {
return (
<MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={true} className='map'>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
{/* the custom control */}
<CustomControl position="bottomleft"></CustomControl>
</MapContainer>
)
}