| name | uui-data-sources |
| description | Helps work with UUI DataSources (ArrayDataSource, LazyDataSource, AsyncDataSource) powering PickerInput, DataTable, FiltersPanel, and other data-driven components. Use when implementing or fixing features that load, filter, sort, or display lists of data. |
UUI Data Sources
UUI DataSources are the core infrastructure for data-driven components like PickerInput, DataTable, FiltersPanel, and PickerModal. They handle loading, filtering, sorting, selection, and tree hierarchies.
Location
- Package:
@epam/uui-core
- Path:
uui-core/src/data/processing/
- Types:
uui-core/src/types/dataSources.ts
DataSource Types
| Type | Use Case | Data Flow |
|---|
| ArrayDataSource | In-memory, synchronous list. Items already loaded. | Pass items array. Filtering/search/sorting done client-side. |
| LazyDataSource | Server-driven, lazy loading. Large or remote data. | api(request, context) fetches on demand. Supports pagination, search, tree. |
| AsyncDataSource | Fetches once via API, then caches. | api(options) called once; results cached and reused across views. |
Hooks (Recommended Usage)
Use hooks instead of instantiating classes directly — they handle lifecycle and prop updates:
import { useArrayDataSource, useLazyDataSource, useAsyncDataSource } from '@epam/uui-core';
useArrayDataSource
For in-memory data:
const dataSource = useArrayDataSource(
{
items: myItems,
getId: (item) => item.id,
getParentId: (item) => item.parentId,
},
[myItems]
);
useLazyDataSource
For server-driven lazy loading:
const dataSource = useLazyDataSource<TItem, TId, TFilter>(
{
api: (request, context) => {
return myApi.fetchItems(request, context);
},
getId: (item) => item.id,
getParentId: (item) => item.parentId,
},
[]
);
API must return { items: TItem[], count?: number, from?: number, cursor?: any }.
useAsyncDataSource
Fetches once, then caches. Good for dropdowns with fixed options:
const dataSource = useAsyncDataSource(
{
api: (options) => svc.api.demo.countries({}, options).then((r) => r.items),
getId: (item) => item.id,
},
[]
);
useView and DataSourceState
Components consume DataSources via useView:
const [dataSourceState, setDataSourceState] = useState<DataSourceState>({});
const view = dataSource.useView(dataSourceState, setDataSourceState);
const rows = view.getVisibleRows();
const listProps = view.getListProps();
view.reload();
DataSourceState (uui-core/src/types/dataSources.ts) includes:
search — search string
filter — filter object (passed to LazyDataSource API)
sorting — sort options
checked — checked item IDs (multi-select)
selectedId — single selected item
folded — tree node fold state
page, pageSize — pagination
focusedIndex, scrollTo — list position
SetDataSourceState is (update: (prev) => DataSourceState) => void — functional update pattern.
Key Config Options
- getId(item) — Required. Returns unique ID.
- getParentId(item) — Optional. For tree hierarchy. LazyDataSource uses it to load parent chain.
- complexIds — Set
true if IDs are objects/arrays (internally JSON.stringified).
- rowOptions / getRowOptions(item) — Row-level options (selectable, checkable, editable).
- cascadeSelection —
true | 'explicit' | 'implicit' for parent-child selection behavior.
- isFoldedByDefault(item, state) — Default fold state for tree nodes.
- selectAll — Enable/disable select-all. Default
true.
LazyDataSource API Contract
type LazyDataSourceApi<TItem, TId, TFilter> = (
request: LazyDataSourceApiRequest<TItem, TId, TFilter>,
context: LazyDataSourceApiRequestContext<TItem, TId>
) => Promise<LazyDataSourceApiResponse<TItem>>;
- Request:
filter, sorting, search, range: { from, count }, ids (for specific IDs), cursor (pagination).
- Context:
parentId, parent when loading tree children.
- Response:
{ items, count?, from?, cursor?, totalCount? }.
Common Patterns
PickerInput with DataSource
const dataSource = useArrayDataSource({ items, getId: (i) => i.id }, [items]);
<PickerInput
dataSource={ dataSource }
value={ value }
onValueChange={ setValue }
getName={ (item) => item.name }
entityName="Item"
/>
DataTable with DataSource
const dataSource = useArrayDataSource({ items, getId: (i) => i.id }, [items]);
const [tableState, setTableState] = useState<DataTableState>({});
const view = dataSource.useView(tableState, setTableState);
<DataTable
getRows={ () => view.getVisibleRows() }
columns={ columns }
value={ tableState }
onValueChange={ setTableState }
/>
Tree with getParentId
const dataSource = useArrayDataSource({
items,
getId: (i) => i.id,
getParentId: (i) => i.parentId,
}, [items]);
LazyDataSource clearCache
When data changes on the server, call dataSource.clearCache() (LazyDataSource only) to force reload.
References
- Data source types:
uui-core/src/types/dataSources.ts
- ArrayDataSource:
uui-core/src/data/processing/ArrayDataSource.tsx
- LazyDataSource:
uui-core/src/data/processing/LazyDataSource.tsx
- AsyncDataSource:
uui-core/src/data/processing/AsyncDataSource.tsx
- Hooks:
uui-core/src/data/processing/hooks/
- Examples:
app/src/docs/_examples/dataSources/, app/src/docs/_examples/pickerInput/, app/src/docs/_examples/tables/