【问题标题】:Why do multiple react-renders break leaflet-draw editing, and how do I fix it?为什么多个反应渲染会破坏传单绘制编辑,我该如何解决?
【发布时间】:2018-09-08 14:29:02
【问题描述】:

解决方法:

到目前为止我能找到的最佳解决方法 - 我会保持打开状态,以防有人想出更好的方法。两部分:

  1. 在下面的更新中分配一个“缓存破坏”键(使用 UUID 或比 Math.random 更好的东西。这将解决最初的问题,但会产生一个新问题,即后续渲染会导致错误编辑时禁用尝试从不再存在的几何体中解开钩子。

  2. 通过跟踪编辑模式并通过在编辑期间返回 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;

【问题讨论】:

  • 目前为止我能找到的最好的解决方法 - 我会保持打开状态,以防有人想出更好的方法,但是:

标签: reactjs react-leaflet leaflet.draw


【解决方案1】:

我在使用 React Leaflet 时也遇到了同样的问题。我非常沮丧,无法编写自己的传单实现作为反应组件。看一看:https://github.com/Chris502/PureLeafletMap

它仍然需要一些能够接受更多配置道具,目前正在处理这些,但我认为这是一个好的开始。

* 编辑 *
这不是反应传单和传单绘制实际问题的答案。这是一个地图组件,可让您加载 geoJSON 特征/绘制和编辑它们,而无需 Edit Mode 布尔值或 shouldComponentUpdate 逻辑。我会举一个可行的例子。

【讨论】:

【解决方案2】:

我也遇到了让 react-leaflet-draw 合作的问题。我也很沮丧,无法在这里实现一个分叉:https://github.com/andrewdodd/react-leaflet-draw

我对 react-leaflet-draw 的主要挫败感是它自动在控件内嵌入了一个 FeatureGroup,它用于在您编辑时存储形状,但您无法与之交互或修改。在以 React 方式(即不是面向 DOM 的 Leaflet.js 方式)做事时,这会导致各种问题,这可能是您正在经历的。

阅读我的 fork 中的代码可能会让您相信编写自己的包装器(或将文件从我的 fork 复制到您的项目中)更容易。

FWIW,“示例”实际上比库本身更难阅读和理解,因为示例必须处理存储状态等。

【讨论】:

    【解决方案3】:

    如果你使用 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>
    )
    

    【讨论】:

      猜你喜欢
      • 2010-10-20
      • 2023-04-04
      • 2016-06-17
      • 1970-01-01
      • 2021-11-03
      • 2011-02-10
      • 1970-01-01
      • 2019-12-06
      • 2022-11-12
      相关资源
      最近更新 更多