Reducing app restart frequency with multiple useRecords hooks in Airtable blocks

I’m building a custom Airtable blocks app that pulls data from several tables. The app shows this info in context and linked together. I’m using useRecords hooks to keep everything up-to-date when users make changes.

But there’s a problem. The app is super slow to load because it keeps restarting with each useRecords hook. Is there a trick to fix this while still getting all the table data I need?

Here’s a simplified version of what I’m doing:

function MyBlocksApp() {
  const db = useDatabase();
  const tableRefs = React.useMemo(() => ({
    items: db.getTableByNameIfExists('Items'),
    prices: db.getTableByNameIfExists('Prices'),
    clients: db.getTableByNameIfExists('Clients'),
    sales: db.getTableByNameIfExists('Sales'),
    staff: db.getTableByNameIfExists('Staff'),
  }), [db]);

  console.log('Connected to tables');

  const salesData = useRecords(tableRefs.sales);
  console.log('Got sales data');
  const staffData = useRecords(tableRefs.staff);
  console.log('Got staff data');
  const priceData = useRecords(tableRefs.prices);
  console.log('Got price data');
  const itemData = useRecords(tableRefs.items);
  console.log('Got item data');
  const clientData = useRecords(tableRefs.clients);
  console.log('Got client data');

  // Rest of the app logic
}

The console shows it’s restarting for each useRecords call. Any ideas on how to make this more efficient?

I’ve dealt with this exact issue in my Airtable blocks, and it can be frustrating. One approach that worked wonders for me was implementing a custom hook to batch the useRecords calls. Here’s a rough idea:

function useMultipleRecords(tableRefs) {
  const [data, setData] = useState({});
  
  useEffect(() => {
    const fetchData = async () => {
      const results = {};
      for (const [key, table] of Object.entries(tableRefs)) {
        results[key] = await table.selectRecordsAsync();
      }
      setData(results);
    };
    fetchData();
  }, [tableRefs]);

  return data;
}

Then in your main component:

const allData = useMultipleRecords(tableRefs);

This approach significantly reduced unwanted restarts and improved load times. It might need some adjustments based on your app’s specific needs, but it’s a solid starting point to optimize your setup.

I’ve encountered similar performance issues when dealing with multiple useRecords hooks. One effective strategy I’ve employed is to leverage the useCallback hook in combination with a custom hook for data fetching. Here’s a simplified approach:

const useTableData = (tableRef) => {
  const [data, setData] = useState([]);
  
  const fetchData = useCallback(async () => {
    const records = await tableRef.selectRecordsAsync();
    setData(records);
  }, [tableRef]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  return data;
};

Then in your main component:

const salesData = useTableData(tableRefs.sales);
const staffData = useTableData(tableRefs.staff);
// ... and so on for other tables

This approach helps minimize unnecessary re-renders and provides better control over when data is fetched. It’s resulted in noticeable performance improvements in my Airtable block apps.

hey there whsperingwind! i’ve run into similar issues with multiple useRecords. one trick that worked for me was combining them into a single hook call, like this:

const [salesData, staffData, priceData, itemData, clientData] = useRecords([tableRefs.sales, tableRefs.staff, tableRefs.prices, tableRefs.items, tableRefs.clients]);

this way it only triggers one restart. hope that helps!