top of page
Writer's pictureWhizzystack Solutions

An Introduction To SWR: React Hooks For Remote Data Fetching


In this article, we’ll be looking at a new way of retrieving data in React Apps named SWR. This is a set of hooks for remote data fetching that makes things easier, such as caching, pagination, and so on. We’ll also be building a Pokedex App from scratch and using SWR features to get data and paginate it.


SWR is a lightweight library created by Vercel (formerly ZEIT) that allows fetching, caching, or refetching data in realtime using React Hooks. It’s built with React Suspense which lets your components “wait” for something before they can render, including data. SWR ships also with great features such as dependent fetching, focus on revalidation, scroll position recovery, and so on. It’s also a very powerful tool since it’s backend agnostic and has good support for TypeScript. It’s a package that has a bright future.

Why should you care? You should care if you’ve been looking for a library that does not only fetch data from APIs but also make it possible to do things like caching and dependent fetching. What will be covered in this tutorial will come in handy when building React applications with a lot of moving parts. It’s expected that you should have made use of Axios and the Fetch API, even though we’ll compare how they differ from SWR, we won’t be going into details on how they’ll be implemented.


In this guide, I will introduce you to React Hooks for Remote Data Fetching by building a Pokedex app that requests data from the Pokemon API. We will also dive into other features that come with SWR as well, and highlight its differences compared to popular solutions such as the Fetch API and the Axios library and give you the reasons why using this library and why you should keep an eye on SWR.


So, let’s start by answering a fundamental question: What is SWR?


With so many people working from home, we thought we would bring our Smashing Workshops from our home offices to yours. Meet online front-end & UX workshops, with practical takeaways, interactive exercises, recordings and a friendly Q&A.




In this article, we’ll be watching a brand new manner of retrieving knowledge in React Apps named SWR. this can be a collection of hooks for remote knowledge winning that produces things easier, like caching, pagination, and so on. We’ll even be building a Pokedex App from scratch and mistreatment SWR options to urge knowledge and number it.

SWR may be a light-weight library created by Vercel (formerly ZEIT) that enables attractive, caching, or refetching information in realtime victimisation React Hooks. It’s engineered with React Suspense that lets your parts “wait” for one thing before they will render, as well as information. SWR ships additionally with nice options like dependent attractive, specialise in revalidation, scroll position recovery, and so on. It’s additionally a really powerful tool since it’s backend agnostic and has sensible support for matter. It’s a package that encompasses a bright future. Why do you have to care? you must care if you’ve been searching for a library that doesn't solely fetch information from Apis however additionally build it doable to try and do things like caching and dependent attractive. can|what is going to|what's going to} be lined during this tutorial will are available in handy once building React applications with tons of moving elements. It’s expected that you just ought to have created use of Axios and therefore the Fetch API, although we’ll compare however they disagree from SWR, we tend to won’t be going into details on however they’ll be enforced. In this guide, i'll introduce you to React Hooks for Remote information attractive by building a Pokedex app that requests information from the Pokemon API. we'll additionally dive into different options that accompany SWR yet, and highlight its variations compared to common solutions like the Fetch API and therefore the Axios library and provides you the explanations why victimisation this library and why you must keep a watch on SWR. So, let’s begin by respondent a basic question.

What Is SWR?

SWR is associate degree initialism of Stale-While-Revalidate. It’s a React Hooks library for remote information taking. SWR works with 3 main steps: 1st, it returns the info from the cache (the stale part), then sends the fetch request (the revalidate part), and at last comes with the up-to-date information. however no worries, SWR handles of these steps for USA. the sole issue we've to try to to is offer the useSWR hook the required parameters to form the request

The only thing we have to do is give the useSWR hook the needed parameters to make the request.


SWR has also some nice features such as:


· Back-end agnostic

· Fast page navigation

· Revalidation on focus

· Interval polling

· Request deduplication

· Local mutation

· Pagination

· TypeScript ready

· SSR support

· Suspense mode

· React Native support

· Lightweight.

· Sounds magical? Well, SWR simplifies things and will increase evidently the user expertise of your React app. And once we have a tendency to begin implementing it in our project, you may see why this hook is handy. It’s vital to grasp that the name of the package is swr or SWR and therefore the hook wont to get SWR options is called useSWR.

· In theory, the SWR is probably what you wish to reinforce your knowledge attractive. However, we have a tendency to have already got 2 nice ways in which of creating HTTP requests in our app: the Fetch API and therefore the Axios library. So, why employing a new library to retrieve data? let’s strive responsive this legit question within the next section.




Comparison With Fetch And Axios


We have already got many ways to create communications protocol requests in our React Apps, and 2 of the foremost in style is that the Fetch API and also the Axios library. they're each nice and permits America to fetch or send knowledge simply. However, once the operation is finished, they're going to not facilitate America to cache or page knowledge, you have got to try and do it on our own. Axios or Fetch can simply handle the request and come back the expected response, nothing additional.

And compared to SWR, it’s a touch totally different as a result of the SWR underneath the hood uses the Fetch API to request knowledge from the server — it’s quite a layer engineered on prime of it.

However, it's some nice options like caching, pagination, scroll position recovery, dependent winning, etc, and to be precise an exact level of reactivity out of the box that Axios or Fetch don't have. It’s an enormous advantage as a result of having such options facilitate to create our React Apps quick and easy and scale back markedly the scale of our code.

And to conclude, simply detain mind that SWR isn't an equivalent as Axios or Fetch although it helps to affect communications protocol requests. SWR is additional advanced than them, it provides some enhancements to stay our app synchronic with the back-end and therefore will increase the performance of our app. Now we all know what’s variations SWR has compared to the Axios library or the Fetch API, it’s time to dive into why victimisation such a tool.

Why Using SWR For Data Fetching?


As I beforementioned earlier SWR ships with some handy options that facilitate to extend the usability of your app simply. With SWR, you'll foliate your information in no-time mistreatment useSWRPages, you'll additionally fetch information that depends on another request or recover a scroll position once you retreat to to a given page, so far more. Usually, we have a tendency to show to the user a loading message or a spinner whereas taking information from the server.

And with SWR, you'll create it higher by showing to the user the cached or stale information whereas retrieving new information from the API. And once that operation is finished, it'll revalidate the info to indicate the redo. And you don’t ought to do something, SWR can cache the info the primary time you fetch it and retrieve it mechanically once a replacement request is formed. So far, we have a tendency to already see why mistreatment SWR over Axios or Fetch is healthier relying clearly on what you're reaching to build. except for several cases,

I will be able to advocate mistreatment SWR as a result of it's nice options that transcend simply taking and returning information. That said, we will currently begin building our React app and use the SWR library to fetch remote information. So, let’s begin by putting in place a replacement project.


Setting Up


As I said earlier in the introduction, we will build an app that fetches data from the Pokemon API. You can use a different API if you want too, I will stick with it for now.

And to create a new app, we need to run the following command on the terminal:


npx create-react-app react-swr

Next, we need to install the SWR library by first navigating to the folder that holds the React app.


cd react-swr

As you can see, the folder structure is simple. The only thing to notice is the components folder that holds the Pokemon.js file. It will be used later as a presentational component to show a single Pokemon once we get data from the API.

Great! With that in place, we can now start fetching data from the API using useSWR.

Fetching Remote Data



The SWR package has some handy options as we've got seen on top of. However, there are basically two ways that of configuring this library: either domestically or globally. A local setup means whenever we have a tendency to produce a replacement file, we've got to setup SWR once more to be ready to fetch remote information. And a world setup permits North American country to employ a district of our configuration inside completely different files as a result of a fetcher operate will be declared once and used all over. And no worries, we are going to see each during this article, except for currently, let’s get hands dirty and add some meaty code within the App.js file.

DISPLAYING THE DATA


import React from 'react'
import useSWR from 'swr'
import { Pokemon } from './components/Pokemon'
 
const url = 'https://pokeapi.co/api/v2/pokemon'
 
const fetcher = (...args) => fetch(...args).then((res) => res.json())
 
function App() {
 const { data: result, error } = useSWR(url, fetcher)
 
 if (error) return <h1>Something went wrong!</h1>
 if (!result) return <h1>Loading...</h1>
 
 return (
 <main className='App'>
 <h1>Pokedex</h1>
 <div>
 {result.results.map((pokemon) => (
 <Pokemon key={pokemon.name} pokemon={pokemon} />
 ))}
 </div>
 </main>
 )
}
export default App

As you'll be able to see, we have a tendency to begin by commercialism useSWR from the SWR library. This declares the URL of the API you would like to urge information from, and a operate to fetch these information.

The operate fetcher is employed here to remodel the info into JSON. It receives the info fetched as associate argument and returns one thing.

Notice that here, i exploit the remainder operator since I’m unsure of the kind and length of information received as a parameter, therefore, I copy everything before passing it once more as associate argument to the fetch methodology provided by use SWR that transforms the info into JSON and returns it.

That said, the fetcher and therefore the URL of the API may be currently passed as parameters to the useSWR hook. With that, it will currently create the request and it returns 2 states: the info fetched and a slip state. And information: result's a similar as data.result, we have a tendency to use object destructuring to tug result from information.

With the came back values, we will currently check if the info is with success fetched then loop through it. And for every user, use the Pokemon part to show it.

Now we've got the info and pass it right down to the Pokemon part, it’s time to update Pokemon.js to be able to receive and show the info.

CREATING THE POKEMON partCREATING THE POKEMON COMPONENT



import React from 'react'
import useSWR from 'swr'
 
const fetcher = (...args) => fetch(...args).then((res) => res.json())
 
export const Pokemon = ({ pokemon }) => {
 const { name } = pokemon
 const url = 'https://pokeapi.co/api/v2/pokemon/' + name
 
 const { data, error } = useSWR(url, fetcher)
 
 if (error) return <h1>Something went wrong!</h1>
 if (!data) return <h1>Loading...</h1>
 
 return (
 <div className='Card'>
 <span className='Card--id'>#{data.id}</span>
 <img
 className='Card--image'
 src={data.sprites.front_default}
 alt={name}
 />
 <h1 className='Card--name'>{name}</h1>
 <span className='Card--details'>
 {data.types.map((poke) => poke.type.name).join(', ')}
 </span>
 </div>
 )
}

Here, we've got a part that receives one Pokemon information from the API and displays it. However, the information received doesn't contain all fields required, thence we've got to create another request to the API to induce the whole Pokemon object.

And as you'll be able to see, we have a tendency to use an equivalent method to retrieve the information even though now we have a tendency to append the name of the Pokemon to the universal resource locator.

By the way, if you're not acquainted with destructuring, () is that the same as receiving props and accessing to the pokemon object with props.pokemon. It’s simply a shorthand to drag out values from objects or arrays.



With that in situ, if you navigate to the foundation folder of the project and run on the terminal the subsequent command:

 yarn start
 

Or if you’re using npm:

 npm start
 

You should see that the data are successfully fetched from the Pokemon API and displayed as expected.




Great! we tend to square measure currently able to fetch remote information with SWR. However, this setup may be a native one and might be a touch redundant as a result of you'll already see that App.js and Pokemon.js use an equivalent fetcher perform to try to to an equivalent issue.

But fortuitously, the package comes with a handy supplier named SWRConfig that helps to tack SWR globally. It’s a wrapper element that permits kid elements to use the worldwide configuration and thus the fetcher perform.

To setup SWR globally, we want to update the index.js file as a result of it’s wherever the App element is rendered victimization React DOM. If you would like, you'll use SWRConfig directly within the App.js file.

CONFIGURING SWR GLOBALLY


import React from 'react'
import ReactDOM from 'react-dom'
import { SWRConfig } from 'swr'
import App from './App'
import './index.css'
 
const fetcher = (...args) => fetch(...args).then((res) => res.json())
 
ReactDOM.render(
 <React.StrictMode>
 <SWRConfig value={{ fetcher }}>
 <App />
 </SWRConfig>
 </React.StrictMode>,
 document.getElementById('root')
)

As you can see, we start by importing SWRConfig which is a provider that needs to wrap the higher component or just part of your React app that needs to use SWR features. It takes as props a value that expects an object of config. You can pass more than one property to the config object, here I just need the function to fetch data.


Now, instead of declaring the fetcher function in every file, we create it here and pass it as value to SWRConfig. With that, we can now retrieve data at any level in our app without creating another function and hence avoid redundancy.


Besides that, fetcher is equal to fetcher: fetcher, it’s just syntactic sugar proposed by ES6. With that change, we need now to update our components to use the global config.


USING THE GLOBAL SWR CONFIGURATION

import React from 'react'
import useSWR from 'swr'
import { Pokemon } from './components/Pokemon'
 
const url = 'https://pokeapi.co/api/v2/pokemon'
 
function App() {
 const { data: result, error } = useSWR(url)
 
 if (error) return <h1>Something went wrong!</h1>
 if (!result) return <h1>Loading...</h1>
 
 return (
 <main className='App'>
 <h1>Pokedex</h1>
 <div>
 {result.results.map((pokemon) => (
 <Pokemon key={pokemon.name} pokemon={pokemon} />
 ))}
  </div>
 </main>
 )
}
export default App

Now we only need to pass the url to useSWR, instead of passing the url and fetcher method. Let’s also tweak the Pokemon component a bit.



import React from 'react'
import useSWR from 'swr'
 
export const Pokemon = ({ pokemon }) => {
 const { name } = pokemon
 const url = 'https://pokeapi.co/api/v2/pokemon/' + name
 
 const { data, error } = useSWR(url)
 
 if (error) return <h1>Something went wrong!</h1>
 if (!data) return <h1>Loading...</h1>
 
 return (
 <div className='Card'>
 <span className='Card--id'>#{data.id}</span>
 <img
 className='Card--image'
 src={data.sprites.front_default}
 alt={name}
 />
 <h1 className='Card--name'>{name}</h1>
 <span className='Card--details'>
 {data.types.map((poke) => poke.type.name).join(', ')}
 </span>
 </div>
 )
}


You can already see that we've got no fetcher operate any longer, because of the world configuration that passes the operate to useSWR underneath the hood. Now, you'll be able to use the world fetcher operate everyplace in your app. the sole issue that the useSWR hook has to fetch remote information is that the URL. However, we will still enhance the setup moreover by making a custom hook to avoid declaring the URL once more and once more, and instead, simply pass as parameter the trail.


ADVANCED SETUP BY CREATING A CUSTOM HOOK


To do so, you have to create a new file in the root of the project named useRequest.js (you can name it whatever you want) and add this code block below to it.

import useSwr from 'swr'
 
const baseUrl = 'https://pokeapi.co/api/v2'
 
export const useRequest = (path, name) => {
 if (!path) {
 throw new Error('Path is required')
 }
 
 const url = name ? baseUrl + path + '/' + name : baseUrl + path
 const { data, error } = useSwr(url)
 
 return { data, error }
}

Here, we've a operate that receives a path and optionally a reputation and appends it to the bottom computer address to make the entire computer address. Next, it checks if a reputation parameter is received or not and handle it consequently. Then, that computer address is passed as a parameter to the useSWR hook to be ready to fetch the remote knowledge and come it. And if no path is passed, it throws a slip-up. Great! We’d like currently to tweak the parts a small amount to use our custom hook.

import React from 'react'
import { useRequest } from './useRequest'
import './styles.css'
import { Pokemon } from './components/Pokemon'
 
function App() {
 const { data: result, error } = useRequest('/pokemon')
 
 if (error) return <h1>Something went wrong!</h1>
 if (!result) return <h1>Loading...</h1>
 
 return (
 <main className='App'>
 <h1>Pokedex</h1>
 <div>
 {result.results.map((pokemon) => (
 <Pokemon key={pokemon.name} pokemon={pokemon} />
 ))}
 </div>
 </main>
 )
}
export default App

Now, rather than victimisation the SWR hook, we have a tendency to use the custom hook engineered on high of it and so pass for sure the trail as Associate in Nursing argument. thereupon in situ, everything can work like before however with a way cleaner and versatile configuration. Let’s conjointly update the Pokemon element.

import React from 'react'
import { useRequest } from '../useRequest'
 
export const Pokemon = ({ pokemon }) => {
 const { name } = pokemon
 const { data, error } = useRequest('/pokemon', name)
 
 if (error) return <h1>Something went wrong!</h1>
 if (!data) return <h1>Loading...</h1>
 
 return (
 <div className='Card'>
 <span className='Card--id'>#{data.id}</span>
 <img
 className='Card--image'
 src={data.sprites.front_default}
 alt={name}
 />
 <h1 className='Card--name'>{name}</h1>
 <span className='Card--details'>
 {data.types.map((poke) => poke.type.name).join(', ')}
 </span>
 </div>
 )
}

You can already see however our custom hook makes things easier and a lot of versatile. Here, we tend to simply ought to pass in addition the name of the Pokemon to fetch to North American countryeRequest and it handles everything for us. I hope you begin enjoying this cool library — but, we tend to still have things to get as a result of SWR offers such a lot of options, and one amongst them is useSWRPages that could be a hook to page knowledge simply. So, let’s use that hook within the project.


PAGINATE OUR DATA WITH useSWRPages


SWR allows us to paginate data easily and request only a part of it, and when needed refetch data to show for the next page.


Now, let’s create a new file in the root of the project usePagination.js and use it as a custom hook for pagination.

import React from 'react'
import useSWR, { useSWRPages } from 'swr'
import { Pokemon } from './components/Pokemon'
 
export const usePagination = (path) => {
 const { pages, isLoadingMore, loadMore, isReachingEnd } = useSWRPages(
 'pokemon-page',
 ({ offset, withSWR }) => {
 const url = offset || `https://pokeapi.co/api/v2${path}`
 const { data: result, error } = withSWR(useSWR(url))
 
 if (error) return <h1>Something went wrong!</h1>
 if (!result) return <h1>Loading...</h1>
 
 return result.results.map((pokemon) => (
 <Pokemon key={pokemon.name} pokemon={pokemon} />
 ))
 },
 (SWR) => SWR.data.next,
 []
 )
 
 return { pages, isLoadingMore, loadMore, isReachingEnd }
}

As you'll be able to see, here we have a tendency to begin by commerce useSWRPages that is that the helper that permits paginating knowledge simply.

It receives four arguments: the key of the request pokemon-page that is additionally used for caching, a perform to fetch the information that returns a element if the information area unit with success retrieved, and another perform that takes the SWR object and request knowledge from succeeding page, associated an array of dependencies.

And once the information fetched, the perform useSWRPages returns many values, however here we want four of them: the pages that's the element came with the information, the perform isLoadingMore that checks if the information area unit presently fetched, the perform loadMore that helps taking additional knowledge, and therefore the technique isReachingEnd that determines whether or not there's still knowledge to retrieve or not.

Now we've the custom hook that returns the required values to page knowledge, we will currently move to the App.js file and tweak it a touch.

import React from 'react'
import { usePagination } from './usePagination'
import './styles.css'
 
export default function App() {
 const { pages, isLoadingMore, loadMore, isReachingEnd } = usePagination(
 '/pokemon'
 )
 
 return (
 <main className='App'>
 <h1>Pokedex</h1>
 <div>{pages}</div>
 <button
 onClick={loadMore}
 disabled={isLoadingMore || isReachingEnd}
 >
 Load more...
 </button>
 </main>
 )
}


Once the usePagination hook foreign, we are able to currently pass the trail as a parameter and acquire back the came back values. And since pages may be a element, we have a tendency to don’t ought to loop through the information or something like that. Next, we have a tendency to use the operate loadMore on the button to fetch a lot of knowledge and disable it if the retrieving operation isn't finished or if there's no knowledge to fetch. Great! thereupon amendment, we are able to currently browse on the foundation of the project and begin the server with this command to preview our app.

yarn start
 

Or if you’re using npm:

 npm start
 

You should see that the data are successfully fetched and if you click on the button, new data will be retrieved by SWR.

So far, we have seen in practice the SWR library, and I hope you are finding value on it. However, it still has some features to offer. Let’s dive into these functionalities in the next section.


The SWR library has a bunch of handy things that simplifies the way we build React apps.


FOCUS REVALIDATION


It’s a feature that permits change or revalidating to be precise the information after you re-focus a page or switch between tabs. And by default, this practicality is enabled, however you'll disable it anyway if it doesn't suit your want. It are often helpful particularly if you have got information with high-level-frequency


REFETCH ON INTERVAL


The SWR library permits refetching information when an exact quantity of your time. It may be handy once your information changes at high speed otherwise you have to be compelled to create a replacement request to urge a bit of recent data from your info.


LOCAL MUTATION


With SWR, you'll be able to set a brief native state that may update mechanically once new information square measure fetched(revalidation). This feature comes live notably after you cope with associate degree Offline-first approach, it helps to update information simply.


SCROLL POSITION RECOVERY


This feature is extremely handy, particularly once it involves addressing immense lists. It permits you to recover the scroll position once obtaining back to the page. And in any case, it will increase the usability of your app.


DEPENDENT FETCHING


SWR permits you to fetch information that depends on alternative information. meaning it will fetch information A, and once that operation is completed, it uses it to fetch information B whereas avoiding waterfalls. And this feature helps after you have relative information.

That said, SWR helps to extend the user expertise in any matter. it's additional options than that, and for several cases it’s higher to use it over the Fetch API or the Axios library.


CONCLUSION


Throughout this text, we've seen why SWR is Associate in Nursing awful library. It permits remote knowledge winning exploitation React Hooks and helps to alter some advanced options out of the box like folio, caching knowledge, refetching on interval, scroll position recovery, and so on. SWR is additionally backend agnostic which implies it will fetch knowledge from any reasonably Apis or databases. In definitive, SWR will increase tons the user expertise of your React apps, it's a bright future and you ought to keep an eye fixed thereon or higher use it in your next React app.


Thanks for reading!


We will be happy to answer your questions on designing, developing, and deploying comprehensive enterprise web, mobile apps and customized software solutions that best fit your organization needs.

As a reputed Software Solutions Developer we have expertise in providing dedicated

remote and outsourced technical resources for software services at very nominal cost. Besides experts in full stacks We also build web solutions, mobile apps and work on system integration, performance enhancement, cloud migrations and big data analytics. Don’t hesitate to get in touch with us!

34 views0 comments

Recent Posts

See All

Comments


bottom of page