Временное решение:
Лучший обходной путь, который я смог найти - я оставлю это открытым, если кто-то придумает что-нибудь получше. Две части:
Назначьте ключ для очистки кэша, как в приведенном ниже обновлении (используйте UUID или что-то лучше, чем Math.random. Это исправит первоначальную проблему, но создаст новую проблему, заключающуюся в том, что последующие рендеры вызовут ошибки при отключении редактирования пытается отсоединиться от уже не существующей геометрии.
Исправьте эту вторичную проблему, отслеживая режим редактирования и отключая рендеринг для компонента карты, возвращая 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;