React Data Fetching Pattern - Part IV
Tags: react, swr, api
Published: 2022-11-16 16:30:39

This article is a continuation of 
* [React Data Fetching Patterns - useState-useEffect](https://dev.to/francisldn/react-data-fetching-patterns-40mg)
* [React Data Fetching Pattern - Custom Hook using Context API](https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg)
* [React Data Fetching Pattern - Redux](https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d)

Click [here](https://github.com/francisldn/React-Data-Fetching-Patterns) to access the Github repo for the code examples discussed below.

<h3>SWR</h3>
From the previous discussions, we see that there are pros and cons with each data fetching method. Could there be a method that is both performant and easy to use? Enter **SWR**.

**SWR** is a relatively recent library created by Vercel, the same team that created NextJS. ``SWR`` stands for *stale-while-revalidate*.

``SWR`` promises 
> 
to supply data to components **constantly** and **automatically**. And the UI will be always fast and reactive. 
> 

To make the data fetching really easy, ``SWR`` provides ``useSWR`` hook which accepts an API url and a callback function (``fetcher``) and then it returns *data* and *error*. There is also an option for ``suspense:true`` with ``useSWR`` hook, which allows for integration with the **React Suspense API**.

React ``Suspense`` API will wait for the data to finish loading before showing the UI to a user. While waiting, a fallback component, such as ``<Loading />`` will be shown to the user.

To make the code reusable and avoid prop-drilling, we can perform the data fetching in a custom hook (``useUsers``), as below. We have to first define a ``fetcher`` function, where the ``getUsers`` function will reside. The ``fetcher`` function will then be passed as a callback function to the ``useSWR`` hook. 

```
const fetcher = async (apiURL:string) => {
    try{
        const {results:data} = await getUsers(apiURL)
        return data.map((user:UserApi) => ({
            id: user.id.value,
            firstName: user.name.first,
            lastName: user.name.last,
            username: user.login.username,
            email: user.email,
        }))
    } catch(error) {
        throw new Error("unable to fetch data")
    }
}

const useUsers = () => {
    const {data, error} = useSWR(apiURL, fetcher,{suspense:true})

    return ({
        users: data,
        loading: !data && !error ? true : false,
        error: error
    })
}

export default useUsers;
```
With the ``useUsers`` hook set up, any react component will now have access to the ``users`` state through the ``useUsers`` hook, as below. 

```
export default function CardList() {
  const { users } = useUsers()

  return (
    <div className="grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 justify-center grid-cols-1 mt-8">
      <Suspense fallback={<Loading />}>
        {users.map((user:User) => (<CardItem key={`${user.id}${user.email}`} user={user}/>))}
      </Suspense>
    </div>
  )
}
```
<h4>Pros</h4>
* As you can see from the codes above, ``useSWR`` greatly simplifies the complexity of the initial code set up to fetch data, and this is done without compromising on performance (it is incredibly performant!). 
* Besides the advantages above, **SWR** also provides other utilities such as data refetching & prefetching, conditional fetching, caching and data refresh interval config.

Now, at this point, I would also like to introduce an alternative library that provides similar utilities as SWR - **React Query**. 

To be continued:
* [React Query](https://dev.to/francisldn/react-data-fetching-pattern-part-v-2oen)

For more information on SWR, see [here](https://swr.vercel.app/docs/getting-started).

***If you like the content, please hit the like button so that it can reach more people.***