I'm having trouble working with FeatureTables and a React component that can be closed and re-opened.
Currently, I create the FeatureTables and then have the component load them by updating the "Container" property of the Feature Tables. However; this only seems to work the first time. When the panel is closed and then re-opened, the references / containers are still pointing to the previous containers which don't exist anymore. The code to update the containers is run, but for some reason it doesn't seem to update in the Feature Tables.
Is there a better way that I should be handling this?
Solved! Go to Solution.
Not sure how you are loading the FeatureTable, but you can use the return function of the useEffect and set featureTable.container = null, to remove the reference and set it when it loads
Something like this
useEffect(() => {
if (table) {
table.container = tableRef.current;
}
else {
table = new FeatureTable({
container: tableRef.current
});
}
return () => table.container = null;
}, [tableRef]);
Not sure how you are loading the FeatureTable, but you can use the return function of the useEffect and set featureTable.container = null, to remove the reference and set it when it loads
Something like this
useEffect(() => {
if (table) {
table.container = tableRef.current;
}
else {
table = new FeatureTable({
container: tableRef.current
});
}
return () => table.container = null;
}, [tableRef]);
@ReneRubalcava Hmmm, good idea. Even when I do that though, the container still seems to be set after the return function has run.
It all depends on how you are managing your components. Can't really tell without a repro.
@ReneRubalcava There's a lot going on, so I might try to make some more changes based on your suggestion to simplify the logic down to a single component before I try posting anything. Other than that, I was more wondering if there were any "best practices" that I should be following when using the FeatureTables with React that might end up solving the problem anyways.
Well, not specific to FeatureTable, but any widget and View, is to use the useEffect cleanup return method to set container null values as needed.
https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1
But if your instantiation logic is a little different, could vary, clean up on route change or some other action.
@ReneRubalcava So, I got it to work, but I had to restructure the application and really condense the FeatureTable portion into a single component. Previously, I was going through an array of Feature Tables to create the containers, but instead, I used the array of layers from the view to map through and create the Components which themselves created the container and FeatureTable. It's a lot clearer now I think, and I didn't need to add / clear the container since the FeatureTable was created and destroyed with the component, although I used a similar useEffect to add / clear the filterGeometry which updates with polygon selections on the map.
import React, { useState, useEffect, useRef } from 'react';
import createFeatureTable from '../../../utils/createFeatureTables';
function LayerTable({mapview, layer, geometry}) {
const [featureTable, setFeatureTable] = useState(null);
const contRef = useRef(null);
useEffect(()=> {
const newFeatureTable = createFeatureTable(mapview, layer, geometry, contRef);
newFeatureTable.then(result => {
setFeatureTable(result);
})
return () => {featureTable && featureTable.destroy()}
}, [])
useEffect(() => {
if (featureTable){
featureTable.filterGeometry = geometry;
}
}, [geometry])
return (
<div ref={contRef}></div>
)
};
export default LayerTable;