我距离React只有2周的时间,虽然我学到了很多东西,但是一些React的想法仍然困扰着我。
现在,我在页面的左半边有一个React-leaflet映射。我上面有3个标记,当我单击每个市场时,它会正确设置setView,因为视点会正确移动。也知道了缩放级别,所以它移动得很好。
//TestMap.jsx
const MapLeaflet = () => {
const mapRef = useRef(null);
const [someLocations] = useState([
[-55, 50],
[-46, 30],
[-64, 71]])
useEffect(() => {
const w = 1000
const h = 1000
const url = "./custommap.jpg"
var map = mapRef.current.leafletElement;
var sw = map.unproject([0, h], 1);
var ne = map.unproject([w, 0], 1);
var bounds = [sw, ne]
const image = L.imageOverlay(
url,
bounds
).addTo(map);
map.fitBounds(image.getBounds());
})
function centerMapView(e) {
const { leafletElement } = mapRef.current;
if (e) {
console.log(e.latlng)
leafletElement.setView(e.latlng, 4);
}
}
return (
<LeafletMap
ref={mapRef}
crs={CRS.Simple}
>
{someLocations.map((position, i) => (
<Marker
position={position}
key={i}
onClick={centerMapView}
>
</Marker>
))}
</LeafletMap>
);
};
export default MapLeaflet;
完美运行。这是我的App.js
class App extends Component {
render() {
return (
<Wrapper>
<Row>
<Col size='6'>
<div style={{ backgroundColor: "#000" }}>
<Testmap />
</div>
</Col>
<Col size='6'>
<p><a href="#loc1">LOCATION1</a></p>
<p><a href="#loc2">LOCATION2</a></p>
<p><a href="#loc3">LOCATION3</a></p>
</Col>
</Row>
</Wrapper>
);
}
}
export default App;
这是问题。我希望网页右半部分的某些链接也能执行相同的操作。基本上是LOCATION1,LOCATION2和LOCATION3。我希望他们将地图移动到匹配位置的中心。
使用常规leaflet.js,我只需要使用onClick事件处理程序调用setView(x,y)。但是我将如何使用React / React-leaflet做到这一点?
我知道我需要传递“ CurPos”(这是我在TestMap中定义的someLocations之一)...或者我可以传递someLocations的索引,例如someLocations [1]?然后什么?
(您可以假设所有标签都已正确定义,因为它们大多只是准引导程序包装器)
几个认识:
a)您不能将状态传递给功能组件,而TestMap是功能组件。我最终将其重写为常规的类组件。
b)然后遇到一堆不兼容问题,因为我不能使用useEffect和类似的东西。我最终使用了createRef,因为它已经被使用过。
c)发现自己绑定到错误的对象,所以不得不更改* centerMapView“的.bind(当它是功能组件时不需要。)>
d)必须添加“此”。一堆其他的东西。
但是最终结果是可行的。链接的名称为handleClick(),该名称在具有somelocations数组中的内容的情况下调用centerMapView2()并将其移动。这可能不是100%正确的运行代码,但应足够接近以使您理解代码。
更新的源代码:
class MapLeaflet extends Component { constructor(props) { super(props); this.mapRef = createRef() // const [curPos, setcurPos] = useState(0) this.centerMapView = this.centerMapView.bind(this) } componentDidMount() { var map = this.mapRef.current.leafletElement; console.log(this.mapRef) const w = 1000 const h = 1000 const url = "./custommap.jpg" L.Marker.prototype.options.icon = customMarker; var sw = map.unproject([0, h], 1); var ne = map.unproject([w, 0], 1); var bounds = [sw, ne] const image = L.imageOverlay( url, bounds ).addTo(map); map.fitBounds(image.getBounds()); } centerMapView(e) { console.log(this) let { leafletElement } = this.mapRef.current; if (e) { leafletElement.setView(e.latlng, 4); } } centerMapView2(id) { let { leafletElement } = this.mapRef.current; var curPos = someLocations[id] leafletElement.setView(curPos, 4); } render() { return ( <Map ref={this.mapRef} crs={CRS.Simple} > {someLocations.map((position, i) => ( <Marker position={position} key={i} className={i} icon={customMarker} onClick={this.centerMapView} > </Marker> ))} </Map> ); } } export default MapLeaflet;
然后app.js看起来像这样:
class App extends Component {
constructor(props) {
super(props);
this.map2Element = React.createRef();
}
state = {}
handleClick = id => {
this.map2Element.current.centerMapView(id - 1)
};
render() {
return (
<Wrapper>
<Row>
<Col size='6'>
<div style={{ backgroundColor: "#000" }}>
<Testmap />
</div>
</Col>
<Col size='6'>
<p><a href="#loc1" key=1 onclick={()=> this.handleClick(location1)}>LOCATION1</a></p>
<p><a href="#loc2" key=2 onclick={()=> this.handleClick(location2)}>LOCATION2</a></p>
<p><a href="#loc3" key=3 onclick={()=> this.handleClick(location3)}>LOCATION3</a></p>
</Col>
</Row>
</Wrapper>
);
}
}
export default App;