Select to view content in your preferred language

FeatureTables in React Application

1251
6
Jump to solution
07-11-2022 11:24 AM
MatthewMuehlhauser2
New Contributor II

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?

0 Kudos
1 Solution

Accepted Solutions
ReneRubalcava
Frequent Contributor II

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]);

View solution in original post

0 Kudos
6 Replies
ReneRubalcava
Frequent Contributor II

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]);
0 Kudos
MatthewMuehlhauser2
New Contributor II

@ReneRubalcava Hmmm, good idea. Even when I do that though, the container still seems to be set after the return function has run.

0 Kudos
ReneRubalcava
Frequent Contributor II

It all depends on how you are managing your components. Can't really tell without a repro.

0 Kudos
MatthewMuehlhauser2
New Contributor II

@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.

0 Kudos
ReneRubalcava
Frequent Contributor II

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.

0 Kudos
MatthewMuehlhauser2
New Contributor II

@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;