I am quite new to Arcgis-JS and React. As suggested here, I am using a functional component with the useEffect
hook to integrate my map.
Now I want to display a line within my map when I click on a certain row of a list. On click I am fetching the appropriate coordinates to be displayed and storing them to a context-variable (dbPageContext.currentGeom
).
The problem: When I want to display another line, the entire map-component has to re-render as I am passing the line-array-variable as a second argument to the useEffect
hook.
const MapComp = () => {
const mapRef = useRef();
const dbPageContext = useContext(DbPageContext);
useEffect(() => {
const mainMap = new Map({
layers: [layer],
basemap: "arcgis-topographic", // Basemap layer service
});
const graphicsLayer = new GraphicsLayer();
mainMap.add(graphicsLayer);
const polyline = {
type: "polyline",
paths: dbPageContext.currentGeom,
};
const simpleLineSymbol = {
type: "simple-line",
color: [0, 230, 250],
width: 4,
};
const polylineGraphic = new Graphic({
geometry: polyline,
symbol: simpleLineSymbol,
});
graphicsLayer.add(polylineGraphic);
const view = new MapView({
container: mapRef.current,
map: mainMap,
spatialReference: {
wkid: 3857,
},
});
return () => {
view && view.destroy();
};
}, [dbPageContext.currentGeom]);
return (
<div>
<div className="webmap" ref={mapRef} />
</div>
);
};
export default MapComp;
How can I update only the graphics-layer without updating the entire map-component? Would be great if someone could help me finding a solution for that.
EDIT: I also tried to implement the map without using the useeffect
hook. But then, nothing was displayed.
You need to separate the effects. On page load, you should have one effect that creates the map. Then a second effect can update the map when dbPageContext.currentGeom
changes.
const MapComp = () => {
const mapRef = useRef();
const dbPageContext = useContext(DbPageContext);
// Memoize this, as you only need to create it once, but you also need
// it to be available within scope of both of the following useEffects
const graphicsLayer = React.useMemo(
() => new GraphicsLayer(),
[]
);
// On mount, create the map, view, and teardown
useEffect(() => {
const mainMap = new Map({
layers: [layer],
basemap: "arcgis-topographic", // Basemap layer service
});
const view = new MapView({
container: mapRef.current,
map: mainMap,
spatialReference: {
wkid: 3857,
},
});
mainMap.add(graphicsLayer);
return () => {
view && view.destroy();
};
}, [])
// When dbPageContext.currentGeom changes, add a polyline
// to the graphics layer
useEffect(() => {
const polyline = {
type: "polyline",
paths: dbPageContext.currentGeom,
};
const simpleLineSymbol = {
type: "simple-line",
color: [0, 230, 250],
width: 4,
};
const polylineGraphic = new Graphic({
geometry: polyline,
symbol: simpleLineSymbol,
});
// Clear previously added lines (if that's what you want)
graphicsLayer.removeAll()
graphicsLayer.add(polylineGraphic);
}, [dbPageContext.currentGeom]);
return (
<div>
<div className="webmap" ref={mapRef} />
</div>
);
};
export default MapComp;