React hook for conveniently use Fetch API.
- Tiny (556 B). Calculated by size-limit
- Both Flow and TypeScript types included
import React from "react";
import useFetch from "react-fetch-hook";
const Component = () => {
const { isLoading, data } = useFetch("https://swapi.co/api/people/1");
return isLoading ? (
<div>Loading...</div>
) : (
<UserProfile {...data} />
);
};
useFetch accepts the same arguments as fetch function.
Install it with yarn:
yarn add react-fetch-hook
Or with npm:
npm i react-fetch-hook --save
Default is response => response.json()
formatter. You can pass custom formatter:
const { isLoading, data } = useFetch("https://swapi.co/api/people/1", {
formatter: (response) => response.text()
});
The useFetch
hook returns an error
field at any fetch exception.
The error
field extends Error
and has status
and statusText
fields equal to Response.
...
const Component = () => {
const { isLoading, data, error } = useFetch("https://swapi.co/api/people/1");
if (error) {
return <div>
<p>Code: ${error.status}</p>
<p>Message: ${error.statusText}</p>
</div>
}
...
};
Multiple useFetch
in the same file/component supported:
const result1 = useFetch("https://swapi.co/api/people/1");
const result2 = useFetch("https://swapi.co/api/people/2");
if (result1.isLoading && result2.isLoading) {
return <div>Loading...</div>;
}
return <div>
<UserProfile {...result1.data} />
<UserProfile {...result2.data} />
</div>
The request will not be called until all elements of depends
array be truthy. Example:
const {authToken} = useContext(authTokenContext);
const [someState, setSomeState] = useState(false);
const { isLoading, data } = useFetch("https://swapi.co/api/people/1", {
depends: [!!authToken, someState] // don't call request, if haven't authToken OR someState: false
});
See example.
If any element of depends
changed, request will be re-call. For example, you can use react-use-trigger for re-call the request:
import createTrigger from "react-use-trigger";
import useTrigger from "react-use-trigger/useTrigger";
const requestTrigger = createTrigger();
export const Subscriber = () => {
const requestTriggerValue = useTrigger(requestTrigger);
const { isLoading, data } = useFetch("https://swapi.co/api/people/1", {
depends: [requestTriggerValue]
});
return <div />;
}
export const Sender = () => {
return <button onClick={() => {
requestTrigger() // re-call request
}}>Send</button>
}
For custom promised function.
import React from "react";
import usePromise from "react-fetch-hook/usePromise";
import callPromise from "..."
const Component = () => {
const { isLoading, data } = usePromise(() => callPromise(...params), [...params]);
return isLoading ? (
<div>Loading...</div>
) : (
<UserProfile {...data} />
);
};
- Basic - Just fetch data with
useFetch
. - Depends - Usage
depends
option for refresh query. - Pagination - Usage
usePaginationRequest
for infinite scroll implementation.
Create a hook wrapper for fetch
call.
useFetch(
path: RequestInfo,
options?: {
...RequestOptions,
formatter?: Response => Promise
depends?: Array<boolean>
},
specialOptions?: {
formatter?: Response => Promise
depends?: Array<boolean>
}
): TUseFetchResult
where TUseFetchResult
is:
{
data: any,
isLoading: boolean,
error: any
}
RequestInfo
, RequestOptions
is fetch args.
usePromise<T, I: $ReadOnlyArray<mixed>>(
callFunction: ?(...args: I) => Promise<T>,
...inputs: I
): TUsePromiseResult<T>
where TUsePromiseResult<T>
is
type TUsePromiseResult<T> = {
data: ?T,
isLoading: boolean,
error: mixed
}
Create a paginated request.
usePaginatedRequest = <T>(
request: (params: { limit: number, offset: number }) => Promise<Array<T>>,
limit: number,
...depends: Array<any>
): {
data: Array<T>,
loadMore?: () => mixed,
hasMore: boolean
};