# react-hooks-fetch

[![CI](https://img.shields.io/github/workflow/status/dai-shi/react-hooks-fetch/CI)](https://github.com/dai-shi/react-hooks-fetch/actions?query=workflow%3ACI)
[![npm](https://img.shields.io/npm/v/react-hooks-fetch)](https://www.npmjs.com/package/react-hooks-fetch)
[![size](https://img.shields.io/bundlephobia/minzip/react-hooks-fetch)](https://bundlephobia.com/result?p=react-hooks-fetch)
[![discord](https://img.shields.io/discord/627656437971288081)](https://discord.gg/MrQdmzd)

Minimal data fetching library with React Suspense

## Introduction

This library provides a React hook `useFetch` for any async functions.
It utilizes React Suspense and `FetchProvider` is required with initial inputs.
The initial inputs are used to run all async function in the initial render.

Project status: Experimental. We need to collect feedbacks.

Design choices:

*   No string keys
*   Force prefetching
*   Cache size one
*   React context based

## Install

```bash
npm install react-hooks-fetch
```

## Usage

```javascript
import React, { Suspense } from 'react';
import { ErrorBoundary } from 'react-error-boundary';

import { FetchProvider, useFetch } from 'react-hooks-fetch';

// 1️⃣
// Create a fetch function.
// The function can take one input argument.
const fetchFunc = async (userId) => {
  const res = await fetch(`https://reqres.in/api/users/${userId}?delay=3`);
  const data = await res.json();
  return data;
};

// 2️⃣
// Define a component to use the fetch function.
// The `refetch` function take a new input argument,
// and it will start fetching before rendering.
const Main = () => {
  const { result, refetch } = useFetch(fetchFunc);
  const handleClick = () => {
    refetch('2');
  };
  return (
    <div>
      <div>First Name: {result.data.first_name}</div>
      <button type="button" onClick={handleClick}>Fetch user 2</button>
    </div>
  );
};

// 3️⃣
// FetchProvider is required with initialInputs.
// We should put ErrorBoundary and Suspense inside FetchProvider.
const App = () => (
  <FetchProvider initialInputs={[[fetchFunc, '1']]}>
    <ErrorBoundary fallback={<h1>Error</h1>}>
      <Suspense fallback={<span>Loading...</span>}>
        <Main />
      </Suspense>
    </ErrorBoundary>
  </FetchProvider>
);
```

## API

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### FetchProvider

FetchProvider component

Put this component higher in the component tree.

#### Parameters

*   `$0` **FetchProviderProps** 

    *   `$0.initialInputs`  
    *   `$0.children`  

#### Examples

```javascript
import { FetchProvider } from 'react-hooks-fetch';

const App = () => (
  <FetchProvider initialInputs={[[fn, input]]}>
    ...
  </FetchProvider>
);
```

### useRefetch

useRefetch hook

This returns only `refetch` part of what `useFetch` returns.

#### Parameters

*   `fn` **FetchFunc\<Input, Result>** 

#### Examples

```javascript
import { useFetch } from 'react-hooks-fetch';

const refetch = useRefetch(desc);
refetch('1');
```

### useFetch

useFetch hook

This is the main hook to be used.

#### Parameters

*   `fn` **FetchFunc\<Input, Result>** 
*   `options` **{allowUndefined: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)}?** 

#### Examples

```javascript
import { useFetch } from 'react-hooks-fetch';

const { input, result, refetch } = useFetch(desc);
```

## Examples

The [examples](examples) folder contains working examples.
You can run one of them with

```bash
PORT=8080 npm run examples:01_minimal
```

and open <http://localhost:8080> in your web browser.

You can also try them in codesandbox.io:
[01](https://codesandbox.io/s/github/dai-shi/react-hooks-fetch/tree/main/examples/01\_minimal)
[02](https://codesandbox.io/s/github/dai-shi/react-hooks-fetch/tree/main/examples/02\_typescript)
[03](https://codesandbox.io/s/github/dai-shi/react-hooks-fetch/tree/main/examples/03\_noinit)

## Blogs

See [History](./HISTORY.md) for previous implementations.

*   [React Hooks Tutorial on Developing a Custom Hook for Data Fetching](https://blog.axlight.com/posts/react-hooks-tutorial-on-developing-a-custom-hook-for-data-fetching/)
*   [useFetch: React custom hook for Fetch API with Suspense and Concurrent Mode in Mind](https://blog.axlight.com/posts/usefetch-react-custom-hook-for-fetch-api-with-suspense-and-concurrent-mode-in-mind/)
*   [Developing a React Library for Suspense for Data Fetching in Concurrent Mode](https://blog.axlight.com/posts/developing-a-react-library-for-suspense-for-data-fetching-in-concurrent-mode/)
*   [Diving Into React Suspense Render-as-You-Fetch for REST APIs](https://blog.axlight.com/posts/diving-into-react-suspense-render-as-you-fetch-for-rest-apis/)

## Translations

This is also available in other languages:

*   ![ko](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/South-Korea.png) **Korean**: [melonbarCode/react-hooks-fetch](https://github.com/melonbarCode/react-hooks-fetch)
*   :cn: **Chinese**: [kaichii/react-hooks-fetch](https://github.com/kaichii/react-hooks-fetch/blob/main/README-zh.md)
