UNPKG

@gravity-ui/data-source

Version:
83 lines (63 loc) 3.06 kB
# Data Source &middot; [![npm version](https://img.shields.io/npm/v/@gravity-ui/data-source?logo=npm&label=version)](https://www.npmjs.com/package/@gravity-ui/data-source) [![ci](https://img.shields.io/github/actions/workflow/status/gravity-ui/data-source/ci.yml?branch=main&label=ci&logo=github)](https://github.com/gravity-ui/data-source/actions/workflows/ci.yml?query=branch:main) **Data Source** is a simple wrapper around data fetching. It is a kind of "port" in [clean architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html). It allows you to make wrappers for stuff around data fetching depending on your use cases. **Data Source** uses [react-query](https://tanstack.com/query/latest) under the hood. ## Installation ```bash npm install @gravity-ui/data-source @tanstack/react-query ``` `@tanstack/react-query` is a peer dependency. ## Getting started Firstly, define a type of error and make your constructors for data sources and your error based on default constructors (makePlainQueryDataSource / makeInfiniteQueryDataSource). For example: ```ts import {makePlainQueryDataSource as makePlainQueryDataSourceBase} from '@gravity-ui/data-source'; export interface ApiError { title: string; code?: number; description?: string; } export const makePlainQueryDataSource = <TParams, TRequest, TResponse, TData, TError = ApiError>( config: Omit<PlainQueryDataSource<TParams, TRequest, TResponse, TData, TError>, 'type'>, ): PlainQueryDataSource<TParams, TRequest, TResponse, TData, TError> => { return makePlainQueryDataSourceBase(config); }; ``` Write a `DataLoader` component based on default. This is convenient to define your display of the loading status and errors. For example: ```tsx import { DataLoader as DataLoaderBase, DataLoaderProps as DataLoaderPropsBase, ErrorViewProps, } from '@gravity-ui/data-source'; export interface DataLoaderProps extends Omit<DataLoaderPropsBase<ApiError>, 'LoadingView' | 'ErrorView'> { LoadingView?: ComponentType; ErrorView?: ComponentType<ErrorViewProps<ApiError>>; } export const DataLoader: React.FC<DataLoaderProps> = ({ LoadingView = YourLoader, ErrorView = YourError, ...restProps }) => { return <DataLoaderBase LoadingView={LoadingView} ErrorView={ErrorView} {...restProps} />; }; ``` Define your first data source: ```ts export const objectDataSource = makePlainQueryDataSource({ // Keys have to be unique. Maybe you should create a helper for making names of data sources name: 'object', // skipContext is just a helper to skip 2 first parameters in the function (context and fetchContext) fetch: skipContext(objectFetch), }); ``` Use it in the application: ```tsx import {useQueryData} from '@gravity-ui/data-source'; export const SomeComponent: React.FC = () => { const {data, status, error, refetch} = useQueryData(objectDataSource, {objectId: 1}); return ( <DataLoader status={status} error={error} errorAction={refetch}> {data && <ObjectComponent object={data} />} </DataLoader> ); }; ```