Być może ten kod Ci pomoże (na przykładzie leaflet). Rysowanie markerów jest umieszczone w render() return
npm
npm install react-leaflet
index.html (tak naprawde jedyna zmiana to umieszczenie css z leaflet)
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Mapa</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>
</head>
<body>
<div id='root'></div>
</body>
</html>
App.css (mapka z leaflet musi mieć hight, border nie jest potrzebny)
.map {
border: 1px solid black;
height: 600px;
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
App.js (zmienne X i Y zamieniłem na lat i lng , dodałem też funkcje do zmiany wartości poza renderem)
- import elementów z leaflet
- state dla tablicy markerów i nowego markera
- addItem - dodaje nowy marker do tablicy markerów i czyści state odpowiedzialny na wyświetlanie value (lat, lng) w formularzu
- updateNewMarkerLat/Lng - zmieniają state nowego markera (onchange)
- w render() / return mapa i rysowanie markerów (wyrysują się bo state się zmieni) + formularz
import React, {Component} from 'react';
import { Map, TileLayer, Marker} from 'react-leaflet';
import './App.css';
class App extends Component {
constructor(){
super();
this.state = {
markers:[{
lat: 51.0331258,
lng: 13.6155611,
}],
newMarker: {
lat: '',
lng: '',
}
}
}
addItem = (e) => {
const markers = this.state.markers
markers.push(this.state.newMarker)
const emptyMarker = {...this.state.newMarker}
emptyMarker.lat = ''
emptyMarker.lng = ''
this.setState({markers:markers,newMarker:emptyMarker})
e.preventDefault();
}
updateNewMarkerLat = (e) => {
const updatedState = {...this.state.newMarker}
updatedState.lat = parseFloat(e.target.value)
this.setState({newMarker:updatedState})
}
updateNewMarkerLng = (e) => {
const updatedState = {...this.state.newMarker}
updatedState.lng = parseFloat(e.target.value)
this.setState({newMarker:updatedState})
}
render(){
return (
<div>
<p>mapa</p>
<Map className='map' center={[51,13.6]} zoom={12}>
<TileLayer attribution='&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>
{this.state.markers.map((position, id) =>
<Marker key={`marker-${id}`} position={position}></Marker>
)}
</Map>
<form onSubmit={this.addItem}>
<input type="number" value={this.state.newMarker.lat} onChange={this.updateNewMarkerLat}/>
<input type="number" value={this.state.newMarker.lng} onChange={this.updateNewMarkerLng}/>
<button type='submit'>dodaj</button>
</form>
</div>
);
}
}
export default App;
Jakoś działa nie wiem jednak czy jest to najbardziej elegancki i zgodny z praktykami sposób - może ktoś jeszcze się wypowie.