我正在学习 React。我想显示一张地图,在该地图上动态显示和隐藏标记。这有效。我用Maplibre GL https://github.com/maplibre/maplibre-gl-js,这是一个分叉地图盒 GL https://docs.mapbox.com/mapbox-gl-js/api/并且处理方式是一样的。
然而不幸的是,当标记发生更改时,地图会重新加载,因为在useEffect
-钩。然而,如果没有它,标记就不会改变。我无法访问外部的地图(变量地图)useEffect
。
有什么可能性可以防止重新加载地图,但可以动态调整标记。
这是我的代码:
import React from "react";
import maplibregl from "maplibre-gl";
const App = () => {
const pois = [
{
display_name: "backery a",
icon: "https://nominatim.openstreetmap.org/ui/mapicons//shopping_bakery.p.20.png",
lat: "50.4",
lon: "7.1",
importance: "0.111",
geojson: '{"type":"Point","coordinates":[7.1,50.4]}',
place_id: "1",
},
{
display_name: "backery b",
icon: "https://nominatim.openstreetmap.org/ui/mapicons//shopping_bakery.p.20.png",
lat: "51.4",
lon: "6.1",
importance: "0.211",
geojson: '{"type":"Point","coordinates":[6.1,51.4]}',
place_id: "2",
},
];
const [searchTerm, setSearchTerm] = React.useState(
localStorage.getItem("search") || "backery a"
);
React.useEffect(() => {
localStorage.setItem("search", searchTerm);
}, [searchTerm]);
const handleSearch = (event) => {
setSearchTerm(event.target.value);
};
const searchedpois = pois.filter((poi) =>
poi.display_name.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
<div>
<h1>React Maplibre Map</h1>
<Search searchValue={searchTerm} onSearch={handleSearch} />
<hr />
<List list={searchedpois} />
<hr />
<Map list={searchedpois} />
</div>
);
};
const Map = (props) => {
React.useEffect(() => {
const map = new maplibregl.Map({
container: "map",
style:
"https://api.maptiler.com/maps/streets/style.json?key=mykey",
center: [7.5, 50.1],
zoom: 4,
});
map.on("load", () => {
props.list.map((item) =>
new maplibregl.Marker().setLngLat([item.lon, item.lat]).addTo(map)
);
});
}, [props.list]);
return <div></div>;
};
const Search = ({ searchValue, onSearch }) => (
<div>
<label htmlFor="search">Suche: </label>
<input id="search" type="text" onChange={onSearch} value={searchValue} />
</div>
);
const List = (props) => (
<div>
<table>
<tbody>
{props.list.map((item) => (
<POI key={item.place_id} poi={item} />
))}
</tbody>
</table>
</div>
);
const POI = ({ poi }) => (
<tr key={poi.place_id}>
<td>{poi.display_name}</td>
<td>{poi.lat}</td>
<td>{poi.lon}</td>
<td>{poi.importance}</td>
<td>
<img alt="" src={poi.icon} />
</td>
</tr>
);
export default App;