Skip to main content

Layers

Introduction

All layers types can be added to a MapView as children:

Live Editor
function Example() {
  return (
    <MapView
      ViewProperties={{ extent: OAHU_EXTENT }}
      MapProperties={{ basemap: "topo-vector" }}
      style={{ height: "300px", width: "100%" }}
    >
      <FeatureLayer url={BENTHIC_FEATURELAYER_URL} />
      <MapImageLayer url={LANDCOVER_IMAGELAYER_URL} />
    </MapView>
  );
}
Result
Loading...

State managed layers

Live Editor
function Example() {
  const [visibleLayers, setVisibleLayers] = useState(["benthic", "landcover"]);

  const toggleLayer = (layerName, checked) => {
    if (checked) {
      setVisibleLayers([...visibleLayers, layerName]);
    } else {
      setVisibleLayers(visibleLayers.filter((l) => l !== layerName));
    }
  };

  return (
    <div>
      <div className="flex flex-col gap-2 mb-2">
        <label>
          <input
            type="checkbox"
            className="mr-2"
            checked={visibleLayers.includes("landcover")}
            onChange={(e) => toggleLayer("landcover", e.target.checked)}
          />
          Land Cover Status
        </label>
        <label>
          <input
            type="checkbox"
            className="mr-2"
            checked={visibleLayers.includes("benthic")}
            onChange={(e) => toggleLayer("benthic", e.target.checked)}
          />
          Benthic Habitat
        </label>
      </div>

      <MapView
        ViewProperties={{ extent: OAHU_EXTENT }}
        MapProperties={{ basemap: "topo-vector" }}
        style={{ height: "300px", width: "100%" }}
      >
        {visibleLayers.includes("benthic") && (
          <FeatureLayer url={BENTHIC_FEATURELAYER_URL} />
        )}
        {visibleLayers.includes("landcover") && (
          <MapImageLayer url={LANDCOVER_IMAGELAYER_URL} />
        )}
        <LayerList position="top-right" />
      </MapView>
    </div>
  );
}
Result
Loading...

State managed visibility

The above scenario manages whether or not a layer present on the map. Under the hood, esrieact calls the .addTo and .remove methods on the map instance with the child layers. If you wish for the layers to remain present on the map, but toggle their visibility, you can manage their visible prop with state:

Live Editor
function Example() {
  const [visibleLayers, setVisibleLayers] = useState(["benthic", "landcover"]);

  const toggleLayer = (layerName, checked) => {
    if (checked) {
      setVisibleLayers([...visibleLayers, layerName]);
    } else {
      setVisibleLayers(visibleLayers.filter((l) => l !== layerName));
    }
  };

  return (
    <div>
      <div className="flex flex-col gap-2 mb-2">
        <label>
          <input
            type="checkbox"
            className="mr-2"
            checked={visibleLayers.includes("landcover")}
            onChange={(e) => toggleLayer("landcover", e.target.checked)}
          />
          Land Cover Visible
        </label>
        <label>
          <input
            type="checkbox"
            className="mr-2"
            checked={visibleLayers.includes("benthic")}
            onChange={(e) => toggleLayer("benthic", e.target.checked)}
          />
          Benthic Habitat Visible
        </label>
      </div>

      <MapView
        ViewProperties={{ extent: OAHU_EXTENT }}
        MapProperties={{ basemap: "topo-vector" }}
        style={{ height: "300px", width: "100%" }}
      >
        <FeatureLayer
          url={BENTHIC_FEATURELAYER_URL}
          visible={visibleLayers.includes("benthic")}
        />
        <MapImageLayer
          url={LANDCOVER_IMAGELAYER_URL}
          visible={visibleLayers.includes("landcover")}
        />
        <LayerList position="top-right" />
      </MapView>
    </div>
  );
}
Result
Loading...

State managed props

Just like visible, any and all non-readonly layer properties can be managed with state:

Live Editor
function Example() {
  const [opacity, setOpacity] = useState(100);
  const [listMode, setListMode] = useState("show");

  return (
    <div>
      <div className="flex gap-10 mb-2">
        <div>
          <h4>List Mode</h4>
          <select
            value={listMode}
            onChange={(e) => setListMode(e.target.value)}
          >
            {["show", "hide", "hide-children"].map((mode) => (
              <option key={mode} value={mode}>
                {mode}
              </option>
            ))}
          </select>
        </div>
        <div>
          <h4>Opacity</h4>
          <input
            type="range"
            value={opacity}
            onChange={(e) => setOpacity(e.target.value)}
          />
        </div>
      </div>

      <MapView
        ViewProperties={{ extent: OAHU_EXTENT }}
        MapProperties={{ basemap: "topo-vector" }}
        style={{ height: "300px", width: "100%" }}
      >
        <MapImageLayer
          url={LANDCOVER_IMAGELAYER_URL}
          opacity={opacity / 100}
          listMode={listMode}
        />
        <LayerList position="top-right" />
      </MapView>
    </div>
  );
}
Result
Loading...

All layers inherit properties from __esri.LayerPropeties, though many layers have other specific properties that can be managed via state.

Refs

Each layer can take a ref, which holds the underlying ArcGIS JS API layer instance:

Live Editor
function Example() {
  const featureLayerRef = useRef<__esri.FeatureLayer>();
  const mapImageLayerRef = useRef<__esri.MapImageLayer>();

  return (
    <div>
      <MapView
        ViewProperties={{ extent: OAHU_EXTENT }}
        MapProperties={{ basemap: "topo-vector" }}
        style={{ height: "300px", width: "100%" }}
      >
        <FeatureLayer ref={featureLayerRef} url={BENTHIC_FEATURELAYER_URL} />
        <MapImageLayer ref={mapImageLayerRef} url={LANDCOVER_IMAGELAYER_URL} />
      </MapView>

      <div className="flex gap-2 mt-2">
        <button onClick={() => console.log(featureLayerRef)}>
          Log FeatureLayer ref
        </button>
        <button onClick={() => console.log(mapImageLayerRef)}>
          Log MapImageLayer ref
        </button>
      </div>
    </div>
  );
}
Result
Loading...

Events

Just like MapView, events can be listened to on any Layer component:

Live Editor
function Example() {
  const [point, setPont] = useState();
  const [logs, setLogs] = useState([]);
  const [basemap, setBasemap] = useState("topo-vector");

  return (
    <div>
      <MapView
        style={{ height: "300px", width: "100%" }}
        MapProperties={{ basemap }}
        ViewProperties={{ extent: OAHU_EXTENT }}
      >
        <FeatureLayer
          url={BENTHIC_FEATURELAYER_URL}
          events={{
            "layerview-create": (e) => {
              setLogs((l) => [...l, `layerview-create: ${e}`]);
            },
          }}
        />
        <MapImageLayer
          url={LANDCOVER_IMAGELAYER_URL}
          events={{
            "layerview-create": (e) => {
              setLogs((l) => [...l, `layerview-create: ${e}`]);
            },
          }}
        />
      </MapView>

      <div className="text-amber-50 bg-black w-full p-3">
        <code className="!bg-black">
          {logs.map((l) => (
            <>
              {l}
              <br />
            </>
          ))}
        </code>
      </div>
    </div>
  );
}
Result
Loading...