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 dependsoption for refresh query.
- Pagination - Usage usePaginationRequestfor 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>
    }
): TUseFetchResultwhere 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
};