Nen*_*nad 4 leaflet react-leaflet
您好,有什么方法可以将 jsx 组件传递给 bindPopup 函数,以便我可以在单击按钮时推送 redux 命令吗?
pointToLayer={(
geoJsonPoint: Feature<Point, DeviceProperties>,
latlng,
) => {
const marker = L.marker(latlng);
marker.setIcon(
markerIcon({ variant: geoJsonPoint.properties.relation }),
);
const sddds = (
<div className="font-quicksand">
<h2>{geoJsonPoint.properties.id}</h2>
<h2>{geoJsonPoint.properties.name}</h2>
<p>{geoJsonPoint.properties.description}</p>
<p>{geoJsonPoint.properties.ownerId}</p>
<a
onClick={() => {
dispatch(setDevice(geoJsonPoint.properties));
}}
>
Open device details
</a>
</div>
);
marker.bindPopup(renderToString(sddds));
return marker;
}}
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用反应传单组件,但这样我就无法将道具传递到每个标记选项中(我的意思是标记作为层)。
这是我想到的两个解决方案,如果有人遇到同样的问题,我想与大家分享。
我使用 leaflet-react Popup组件的问题是,当我只映射 geojson 对象时,它不会将 geojson 属性传递给标记层,因为 React-leaflet Marker没有像 geojson 层那样的 api,我需要通过访问这些属性地图其他部分的标记图层。
解决方案一:
在 pointToLayer 方法中使用 ReactDOM.render(),react 将显示有关纯函数的警告,但它会起作用。你只是不应该渲染导入的组件,因为它会抱怨 store 和 redux 提供者,而是将组件代码粘贴到渲染中。如果您想避免警告,请创建另一个函数/挂钩并将其 useEffect() 内的代码渲染到容器(div 或其他内容)。
这是示例:
const popup = L.popup();
const marker = L.marker(latlng);
const container = L.DomUtil.create('div');
render(
<div>
<h2>{props.id}</h2>
<h2>{props.name}</h2>
<p>{props.description}</p>
<p>{props.ownerId}</p>
<a onClick={() => dispatch(setDevice(geoJsonPoint.properties))}></a>
</div>,
container,
);
popup.setContent(container);
marker.bindPopup(popup);
return marker;
Run Code Online (Sandbox Code Playgroud)
使用自定义钩子/函数:
const useRenderPopup = (props) => {
const container = L.DomUtil('div');
const dispatch = useAppDispatch()
useEffect(() => {
render(
<div>
<h2>{props.id}</h2>
<h2>{props.name}</h2>
<p>{props.description}</p>
<p>{props.ownerId}</p>
<a onClick={() => dispatch(setDevice(props.geoJsonPoint.properties))}></a>
</div>,
container,
);
},[])
return container;
}
Run Code Online (Sandbox Code Playgroud)
只需像 popup.setContent(useRenderPopup(someprop)) 这样调用这个函数,这样就不会出现警告。
解决方案2:
使用 renderToString() 和其他需要触发 redux update 附加事件侦听器的东西将所有内容渲染为静态。
const popup = L.popup();
const marker = L.marker(latlng);
const link = L.DomUtil.create('a');
const container = L.DomUtil.create('div');
const content = <DeviceSummary {...geoJsonPoint.properties} />;
marker.setIcon(markerIcon({ variant: geoJsonPoint.properties.relation }));
link.addEventListener('click', () =>
dispatch(setDevice(geoJsonPoint.properties)),
);
link.innerHTML = 'Show device details';
container.innerHTML = renderToString(content);
container.appendChild(link);
popup.setContent(container);
marker.bindPopup(popup);
return marker;
Run Code Online (Sandbox Code Playgroud)
这里的 DeviceSummary 组件是静态的,因此我将其渲染为字符串,然后附加链接,并将 redux 回调添加为事件侦听器。
(除了自定义函数示例之外,这两种解决方案都进入 geoJSON 层内的 pointToLatyer 方法)