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.
- Host: GitHub
- URL: https://github.com/liamross/use-data
- Owner: liamross
- License: mit
- Created: 2019-05-03T01:06:26.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2020-09-04T20:50:17.000Z (almost 6 years ago)
- Last Synced: 2025-09-09T19:14:36.851Z (9 months ago)
- Topics: async, data, hook, hooks, react
- Language: TypeScript
- Size: 463 KB
- Stars: 2
- Watchers: 1
- Forks: 1
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Use Data [](https://travis-ci.org/liamross/use-data) [](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;
}
```