An open API service indexing awesome lists of open source software.

https://github.com/liamross/use-data

A React hook for async fetching of data, data manipulation, and take latest vs take every functionality.
https://github.com/liamross/use-data

async data hook hooks react

Last synced: 5 months ago
JSON representation

A React hook for async fetching of data, data manipulation, and take latest vs take every functionality.

Awesome Lists containing this project

README

          

# Use Data [![Build Status](https://travis-ci.org/liamross/use-data.svg?branch=master)](https://travis-ci.org/liamross/use-data) [![NPM Version](https://badge.fury.io/js/use-data.svg)](https://www.npmjs.com/package/use-data)

1. Fetches data from an async function
1. Allows you to manipulate the data à la Redux
1. Will throw out outdated API calls by default

Basic usage:

```tsx
import React, {FC} from 'react';
import useData from 'use-data';
import {someApi} from './someApi';

const FunctionalComponent: FC<{someProp: string}> = ({someProp}) => {
const {loading, error, data} = useData(() => someApi(someProp));

if (error) return

Error...

;
if (!data || loading) return

Loading...

;
return

{data.someString}

;
};
```

Expand for more advanced usage:

```tsx
import React, {FC, useEffect} from 'react';
import useData from 'use-data';
import {getUser} from './getUserAPI';

const FunctionalComponent: FC<{userId: string}> = ({userId}) => {
const {loading, error, data, fireFetch, setData} = useData(
() => getUser(userId),
{username: '', age: 0},
{fireOnMount: false, takeEvery: true},
);

useEffect(() => {
// Wait for userId to fetch (see fireOnMount is false).
if (userId) fireFetch();
}, [fireFetch, userId]);

const handleSetUsername = () => {
// Uses the function option for newData in order to only change username.
setData(oldUser => ({...oldUser!, username: 'John Doe'}));
};

if (error) return

Error...

;
if (!data || loading) return

Loading...

;
return (
<>

{data.username}



{"Set username to 'John Doe'"}

>
);
};
```

Expand for setting up hook with Context:

```tsx
import React, {createContext, FC} from 'react';
import useData, {StatusObject} from 'use-data';
import {getName} from './getNameAPI';

interface ContextData {
firstName: string;
lastName: string;
}

export const NameContext = createContext>({
loading: false,
error: new Error('No Provider'),
data: null,
fireFetch: () => new Error('No Provider'),
setData: () => new Error('No Provider'),
});

export const NameProvider: FC = ({children}) => {
const statusObject = useData(getName);

return (
{children}
);
};
```

## API

The `useData` hook is the only non-type export. The type definition is as
follows:

```ts
declare function useData(
asyncFetch: () => Promise,
initialData?: D,
options?: UseDataOptions,
): StatusObject;
```

If you are using this in a TypeScript project, you do not need to provide a type
for the generic `D`, as it will be automatically parsed from the return type of
`asyncFetch`. However in some cases it may be desirable to define it (see more
information in the `initialData` section).

It accepts three arguments:

#### `asyncFetch` - _`() => Promise`_

Any async fetch function that you want to use to fetch data from. The type will
be automatically parsed from the return type.

Example usage:

```ts
// If your function takes no arguments, you can pass it in directly:
const {loading, error, data} = useData(asyncFetch);

// If it requires arguments, wrap it in an arrow function:
const {loading, error, data} = useData(() => asyncFetch(someValue));
```

#### `initialData` - _`D`_

Initial data must match the return type of `asyncFetch`, or the generic `D`. For
example, the following will result in an error:

```ts
const {loading, error, data} = useData(
async () => {
return {a: {b: 'b contents'}};
},
{a: null},
);
```

This is because it expects `initialData` to be of type `{ a: { b: string; }; }`.
To fix this, you will need to define the generic:

```ts
const {loading, error, data} = useData<{a: null | {b: string}}>(
async () => {
return {a: {b: 'b contents'}};
},
{a: null},
);
```

This will allow the property `a` to be either null or `{ b: string; }`.

#### `options` - _`UseDataOptions`_

Options is an optional object that has the following structure:

```ts
export interface UseDataOptions {
fireOnMount?: boolean;
takeEvery?: boolean;
}
```

1. `fireOnMount` - Default: _true_. Should the hook fire the `asyncFetch` on
mount.
1. `takeEvery` - Default: _false_. Should the hook take every call rather than
throwing out active calls when new ones are made.

#### `@returns` - _`StatusObject`_

The hook returns an object with 5 properties:

1. `loading` - True if currently fetching.
1. `error` - The error object if your fetch fails, or null if not failed.
1. `data` - The data from your async fetch, or null if not fetched.
1. `fireFetch` - Fire the async function that was provided to useData. You may
pass it an async function to call instead of `asyncFetch`,
1. `setData` - Mutate the data. Either a function that takes old data and
returns the new data, or data of type `D`. Calling this will turn `error` to
null. Additionally takes a parameter to stop loading when called (loading
will continue by default).

```ts
interface UseDataState {
loading: boolean;
error: Error | null;
data: D | null;
}

interface StatusObject extends UseDataState {
fireFetch: (newAsyncFetch?: () => Promise) => void;
setData: (
newData: D | ((oldData: D | null) => D),
stopLoading?: boolean,
) => void;
}
```