# useLoadable

**Kind:** Function

When you're writing an extension, not all of the data in your base is available to work with straight
away. We need to load it from Airtable first. This hook is a low-level tool for managing that.
You might not need to use it directly though - if you're working with a `RecordQueryResult`, try
`useRecords`, `useRecordIds`, or `useRecordById` first.

When you need to use a loadable model, `useLoadable(theModel)` will make sure that the model is
loaded when your component mounts, and unloaded when your component unmounts. By default, you
don't need to worry about waiting for the data to load - the hook uses React Suspense to make
sure the rest of your component doesn't run until the data is loaded. Whilst the data is
loading, the entire extension will show a loading indicator. If you want to change where that
indicator shows or how it looks, use [`<React.Suspense />`](https://reactjs.org/docs/react-api.html#reactsuspense|)
around the component that uses the hook.

You can pass several models to `useLoadable` in an array - it will load all of them simultaneously.
We'll memoize this array using shallow equality, so there's no need to use `useMemo`.

If you need more control, you can pass `{shouldSuspend: false}` as a second argument to
the hook. In that case though, `useLoadable` will cause your component to re-render whenever the
load-state of any model you passed in changes, and you should check each model's `.isDataLoaded`
 property before trying to use the data you loaded.

```js
import {useCursor, useLoadable, useWatchable} from '@airtable/blocks/ui';

 function SelectedRecordIds() {
     const cursor = useCursor();
     // load selected records
     useLoadable(cursor);

     // re-render whenever the list of selected records changes
     useWatchable(cursor, ['selectedRecordIds']);

     // render the list of selected record ids
     return <div>Selected records: {cursor.selectedRecordIds.join(', ')}</div>;
 }
```

```js
import {useLoadable} from '@airtable/blocks/ui';

 function LoadTwoQueryResults({queryResultA, queryResultB}) {
     // load the queryResults:
     useLoadable([queryResultA, queryResultB]);

     // now, we can use the data
     return <SomeFancyComponent />;
 }
```

```js
import {useLoadable, useBase} from '@airtable/blocks/ui';

 function LoadAllRecords() {
     const base = useBase();

     // get a query result for every table in the base:
     const queryResults = base.tables.map(table => table.selectRecords());

     // load them all:
     useLoadable(queryResults);

     // use the data:
     return <SomeFancyComponent queryResults={queryResults} />;
 }
```

**Parameters:**
- `models` (`ReadonlyArray<LoadableModel | null> | LoadableModel | null`) — The models to load.
- `opts` (`UseLoadableOpts`) — Optional options to control how the hook works.

**Returns:** `void`
