Почему несколько реагирующих рендеров нарушают редактирование листовки и как это исправить? - PullRequest
0 голосов
/ 08 сентября 2018

Временное решение:

Лучший обходной путь, который я смог найти - я оставлю это открытым, если кто-то придумает что-нибудь получше. Две части:

  1. Назначьте ключ для очистки кэша, как в приведенном ниже обновлении (используйте UUID или что-то лучше, чем Math.random. Это исправит первоначальную проблему, но создаст новую проблему, заключающуюся в том, что последующие рендеры вызовут ошибки при отключении редактирования пытается отсоединиться от уже не существующей геометрии.

  2. Исправьте эту вторичную проблему, отслеживая режим редактирования и отключая рендеринг для компонента карты, возвращая falseComponentUpdate false на время редактирования, что-то вроде этого:

    shouldComponentUpdate(){
        return !isEditingGeometry();
    }
    

Обновление:

С тех пор, как я это опубликовал, я начал работать с предположением, что это проблема жизненного цикла DOM / React. Это «решает» проблему самым глупым из возможных способов:

<Polygon key={Math.random()} positions={positions}/>

Я собираюсь оставить вопрос открытым, если у кого-то есть идея получше, или я придумаю более надежное решение, но сейчас у меня сложилось впечатление, что эта проблема не в моем коде, а что-то в одном или больше библиотек, но я не уверен, как приступить к исправлению, и я немного озадачен тем, что это не известная проблема. Неужели кто-то где-то использует розыгрыш призов?


Вопрос:

У меня есть проект, в котором я пытаюсь использовать инструменты редактирования листовок в контексте реакции. Ниже приведен пример самой базовой реализации, которая отражает то, что я делаю. Если вы создадите новое приложение create-Reaction-app и замените App.js этим кодом, вы можете запустить его и увидеть ошибку.

Что происходит: карта отображается, фигуры отображаются. Если вы нажмете кнопку «Редактировать», геометрии получат маркеры, и вы сможете их настроить. Это все хорошо.

Если происходит последующий рендеринг (я подделываю это в примере кода, изменяя состояние с помощью таймера), тогда, когда вы нажимаете edit, геометрии получают маркеры, но не могут быть отрегулированы - перемещаются только маркеры. Отмена и повторное нажатие кнопки «Редактировать» (перед другой визуализацией) позволяет редактировать фигуры.

Это сводит меня с ума - я сталкивался с несколькими сообщениями, которые указывают на общую проблему с рисованием листовок и редактированием полигонов после версии 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;

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

У меня также были проблемы с принуждением к взаимодействию. Я тоже достаточно расстроился, чтобы реализовать здесь форк: https://github.com/andrewdodd/react-leaflet-draw

Основное разочарование, которое у меня возникло при реагировании на листовки, заключается в том, что он автоматически внедряет FeatureGroup в элемент управления, который используется для хранения фигур во время редактирования, но вы не можете взаимодействовать или изменять. Это вызывает всевозможные проблемы при выполнении действий способом React (т.е. не DOM-ориентированным способом leaflet.js), что, вероятно, является тем, что вы испытываете.

Чтение кода в моем форке, вероятно, убедит вас в том, что проще написать собственную оболочку (или скопировать файлы из моего форка в ваш проект).

FWIW, «пример» на самом деле сложнее для чтения и понимания, чем сама библиотека, поскольку пример имеет дело с сохранением состояния и т. Д.

0 голосов
/ 26 февраля 2019

Я столкнулся с такими же проблемами, работая и с React Leaflet. Я достаточно расстроился, чтобы написать собственную реализацию листовки в качестве реагирующего компонента. Взгляните: https://github.com/Chris502/PureLeafletMap

Нужно, чтобы некоторые из них могли принять еще несколько конфигурационных реквизитов, сейчас они работают над ними, но я думаю, что это хорошее начало.

* Редактировать *
Это не ответ на реальную проблему с реакцией листовки и розыгрыша листовок. Это компонент карты, который позволит вам загружать / редактировать объекты geoJSON и редактировать их, не прибегая к логическим значениям Edit Mode или shouldComponentUpdate. Я приведу рабочий пример.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...