解决方法:
到目前为止,我能找到的最好的解决方法-如果有人提出更好的建议,我将保持开放。两部分:
分配一个“缓存清除”键,如下面的更新所示(使用UUID或比Math.random更好的东西。这将解决最初的问题,但会产生一个新的问题,即后续的渲染会导致错误
通过跟踪编辑模式并通过在编辑过程中返回shouldComponentUpdate false来禁用地图组件的渲染来解决此次要问题,如下所示:
shouldComponentUpdate(){
return !isEditingGeometry();
}
更新:
自从我发布此内容以来,我就开始假设这是DOM / React生命周期问题。这样可以以最愚蠢的方式“解决”该问题:
<Polygon key={Math.random()} positions={positions}/>
如果有人有更好的主意或者我想出一个更强大的解决方法,我将保留这个问题,但是现在我的印象是这个问题不在我的代码中,而是在一个代码中或更多的库,但是我不确定如何设置它,而令我困惑的是这不是一个已知问题。肯定有人在某处的生产中使用传单抽签吗?
问题:
我有一个项目,在这个项目中我试图在react上下文中使用传单绘制编辑工具。下面是此操作的最基本实现示例,它反映了我在做什么。如果您创建一个新的create-react-app并将此代码替换为App.js,则可以运行它并查看错误。
会发生什么:地图渲染,形状渲染。如果单击“编辑”按钮,则将为几何图形指定手柄,您可以对其进行调整。很好。
如果随后发生渲染(我通过使用计时器更改状态来在示例代码中对此进行伪造),则在单击“编辑”时,几何将接收到手柄,但无法调整-仅手柄会移动。取消并再次单击“编辑”(在另一个渲染之前),可以编辑形状。
这让我发疯-我遇到过几篇文章,指出在4.12版之后,传单绘制和多边形编辑存在一般性问题,但是锁定该版本似乎无济于事(我只是得到了一笔奖励大量已弃用的警告)。
这是库中的错误,还是我在未看到的反应方面做了一些愚蠢的事情?任何想法,甚至功能性的解决方法,我们深表感谢。
Relevant lines from package.json:
"react": "^16.2.0",
"react-leaflet": "^1.8.0",
"react-leaflet-draw": "^0.18.0",
"leaflet": "^1.3.0",
"leaflet-draw": "^0.4.9",
import React, {Component} from 'react';
import './App.css';
import {
Map,
Circle,
LayersControl,
FeatureGroup,
Polygon,
TileLayer
} from 'react-leaflet';
import {EditControl} from "react-leaflet-draw"
class App extends Component {
constructor(props) {
super(props);
this.state={
thing:'stuff'
}
}
componentDidMount(){
// This is a demo hack just to force a second render
setTimeout(() => {
this.setState({thing:'otherstuff'});
}, 2000);
}
render() {
console.log("Render...");
// Building geometries like this into an array and then in return
// mimics what my production code is doing, but I see the same problem
// if I put the geometry JSX inline below
let positions =[[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]];
let tileServerURL='http://tile.stamen.com/watercolor/{z}/{x}/{y}.png';
let editableGeometry = [];
editableGeometry.push(<Circle key="circle" center={[37, -109.05]} radius={2000} />);
editableGeometry.push(<Polygon key="polygon" positions={positions}/>);
return (
<div style={{width:'100vw',height:'100vh'}}>
<Map ref='map' center={[37, -109.05]} zoom={13} className="ps_n3_mapComponent" style={{width:'100vw',height:'100vh'}}>
<LayersControl position='topright'>
<TileLayer key="tilelayer" url={tileServerURL}/>
<FeatureGroup ref='editableFeaturegroup'>
<EditControl/>
{editableGeometry}
</FeatureGroup>
</LayersControl>
</Map>
</div>);
}
}
export default App;
答案 0 :(得分:0)
在使用React Leaflet时,我也遇到了同样的问题。我很沮丧,无法编写自己的传单实现作为React组件。看看:https://github.com/Chris502/PureLeafletMap
它仍然需要一些才能接受更多的配置道具,目前正在使用这些配置道具,但是我认为这是一个好的开始。
*编辑*
这不能解决react-leaflet和leaflet-draw的实际问题。这是一个地图组件,可让您加载geoJSON要素/绘制并编辑它们,而无需使用Edit Mode
布尔值或shouldComponentUpdate
逻辑。我将得到一个可行的例子。
答案 1 :(得分:0)
我在让反应传单画画合作方面也遇到了问题。我也很沮丧,无法在此处实施分叉:https://github.com/andrewdodd/react-leaflet-draw
我对react-leaflet-draw的主要挫败是它自动将FeatureGroup嵌入控件中,用于在编辑时存储形状,但是不能与之交互或修改。在执行React方法(即不是面向DOM的leaflet.js方法)时,这会引起各种问题,这很可能就是您遇到的问题。
在我的fork中读取代码可能会使您相信,编写自己的包装程序(或将文件从fork复制到您的项目中)更加容易。
FWIW,“示例”实际上比库本身更难以阅读和理解,因为示例必须处理存储状态等。
答案 2 :(得分:0)
如果使用react功能组件,则多边形坐标来自props。您应该使用useEffect和useState,并且当props更改整个组件的重新渲染时。
const EditPolygon = ({ coordinates }: OwnProps) => {
const [polygonData, setPolygonData] = useState()
useEffect(() => {
setPolygonData(coordinates)
}, [coordinates])
return (
<FeatureGroup>
<EditControl />
<Polygon positions={coordinates} key={some.id}>
</FeatureGroup>
)