Help

Block reloads when state changes inside app

Topic Labels: Custom Extensions
1216 1
cancel
Showing results for 
Search instead for 
Did you mean: 
David_Wisdom
4 - Data Explorer
4 - Data Explorer

Sometimes when state changes in my application the entire block reloads and this destroys the workflow of the entire application. How do I fix it

1 Reply 1
somehats
6 - Interface Innovator
6 - Interface Innovator

Hi David,

This sounds like an issue with React Suspense, the mechanism that the blocks SDK uses to show a loading indicator whilst data is loading.

Whenever you call useRecords (or similar) on a new set of data, we need to load that data into the block before we can display it to users. Whilst we wait for the data to load, React ‘suspends’ and the block is set up to show a default loading spinner.

There are a couple of ways around this that you could try. The first is to use a custom <React.Suspense fallback={...}> wrapper. You can place this wrapper around any react components that might suspend to customize the loading UI that gets shown whilst we wait for the data to load, or change where that loading UI shows. Docs here: https://reactjs.org/docs/react-api.html#reactsuspense

The alternative is to not use suspense at all. Instead of using useRecords, you could manually load a query like this:

function MyBlockWithCustomLoading(props) {
    const table = props.table;
    // create a query of all the records in the table
    const queryResult = table.selectRecords();
    
    // re-render this component whenever the records in that query change.
    // this is how `useRecords` works under the hood
    useWatchable(queryResult, ['cellValues', 'records'])

    // manually load the data by calling loadDataAsync.
    // when the query result changes or the component unmounts,
    // unload the data.
    useEffect(() => {
        queryResult.loadDataAsync();
        return () => {
            queryResult.unloadData();
        };
    }, [queryResult]);

    // now, we can inspect queryResult.isDataLoaded to control what
    // happens whilst data is loading:
    if (!queryResult.isDataLoaded) {
        return <div>loading...</div>;
    }

    // and we can use queryResult.records to get at individual records:
    return <div>There are {queryResult.records.length} records in this table</div>;
}

The docs for RecordQueryResult might help.