Skip to main content

Props

Vanilla ESRI component properties are class-based, and often circular. For example:

// Using vanilla ArcGIS JS API

const view = new MapView({
extent: new Extent({
xmin: 10,
xmax: 100,
ymin: -20,
ymax: 120,
spatialReference: new SpatialReference({
wkid: 102100,
}),
}),
});

Beacuse react-wrapped ESRI component props extend directly from ESRI class options, this would technically work:

import React from "react";
import { FeatureLayer, MapView } from "./esri";

export const ReactMap: React.FC = ({ layerList }) => {
return (
<MapView
extent={new Extent({
xmin: 10,
xmax: 100,
ymin: -20,
ymax: 120,
spatialReference: new SpatialReference({
wkid: 102100
})
})}
/>
);
};

However, any propery then updated within the above new Extent would not register as a property change with react. The reason for this is that many ArcGIS class-based instance properties are non-Enumerable, and as such, React will not know they have been changed, and will not update the property accordingly. For example, this will not work as expected:

import React from "react";
import { FeatureLayer, MapView } from "./esri";
import FeatureEffect from '@arcgis/core/layers/FeatureEffect'
import FeatureFilter from '@arcgis/core/layers/FeatureFilter'

export const ReactMap: React.FC = ({ layerList }) => {
const [clause, setClause] = useState("SOME SQL CLAUSE");

return (
<MapView>
<FeatureLayer featureEffect={new FeatureEffect({
filter: new FeatureFilter({
where: clause
})
})} />
</MapView>
);
};

Because the property being updated is deeply nested within class-based ESRI components, whose resultant properties are non-enumerable, react will not sense the change and will not update the component. However, most ESRI component properties accept simple objects as option parameters that get auto-casted to their corresponding class constructor:

import React from "react";
import { FeatureLayer, MapView } from "./esri";

export const ReactMap: React.FC = ({ layerList }) => {
const [clause, setClause] = useState("SOME SQL CLAUSE");

return (
<MapView>
<FeatureLayer featureEffect={{
filter: {
where: clause
}
}} />
</MapView>
);
};

It is prefereable to use this second syntax in this codebase. (Though in the case of trying to filter a FeatureLayer, it is preferable to use a definitionExpression for server-side filtering, or a <FeatureLayerView /> component with a filter applied for front-end filtering).

Note that attempting to update any readonly properties via props or state, on any ArcGIS JS API instance, will fail.