An Easy Way to Make API Calls: Redux Toolkit

An Easy Way to Make API Calls: Redux Toolkit

Fetch API data easily on your React App

When I started learning React, I remember among the complaints made by React developers, one seemed to stand out the most—Redux! A predictable state container for JavaScript and React applications has been a nightmare for most React developers, ranging from its difficulty in configuring to its steep learning curve especially for new React developers. These criticisms led the Redux team to come up with a solution—Redux Toolkit, this package was developed to address the issues of

  • Difficulty in configuration
  • Setting up too many packages
  • Redux using too many boilerplate code

Among many other uses, Redux Toolkit provides an easy method of fetching API data, although not a complete replacement of Axios nor Superagent, it covers the majority of the things you need to interact with any API.

Prerequisites

  • This article does not require prior knowledge of Redux. If you haven't worked with Redux before, that's not a problem.
  • This article requires basic knowledge of React
  • This article requires basic knowledge of API call actions
  • A willingness to learn something new and easier

If you haven't worked with an API before hence you don't really understand how it works, read this article.

Now let's dive straight in!

Getting Started

We will be using the official create-react-app boilerplate, and we will be fetching data from a free cryptocurrency API known as Coinranking using the RapidAPI platform.

1. Installing Redux Toolkit Package

To install the Redux Toolkit Package, open up your terminal and type the code below:

# NPM
npm install @reduxjs/toolkit
# Yarn
yarn add @reduxjs/toolkit

2. Create the store

Now we need to create a file called store.js. This file contains the application's state, to create this file, we will create a folder in the root of our react App called app, inside of our app folder 📁, we will create the store.js file 🗃️.

Now, copy this code inside the store.js

import { configureStore } from '@reduxjs/toolkit';


export default configureStore({
    reducer: {   }
})

The reducer parameter will contain an empty object for now. Great!

3. Import the store

Navigate to the index.js file 🗃️, and copy the following code:


 import React from 'react';
import ReactDOM from  'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';


// import the provider object
import { Provider } from 'react-redux';

// import your store 
import store from './app/store';

ReactDOM.render(
<Router>
{/* wrap your app with the provider object */}
<Provider store={store}> 
   <App/>
</Provider>
</Router>
, document.getElementById('root'));

Let me break it down, first we imported our store file to the index.js file

Secondly, we imported the { Provider }, and wrapped our App with the { Provider }. This makes it possible for every component in the app to have access to the store variable. Also notice that the app is wrapped with Router as well, this is coming from react-router-dom, I will be using routers for this article.

4. Create theservices folder

At this stage, we will navigate to our src folder, in there, we will create a folder 📁 named services. This is where Redux Toolkit will fetch the data from the API, just inside of the folder, create your API file, in this case, we will name it cryptoApi.js. Important API parameters like the headers, endpoints will be structured in this file using Redux Toolkit's createApi() method.

5. Create your Coinranking API key

Now we want to fetch the data from the API, to do this, we would need a key which would enable us to get these data.

Platforms like RapidApi give access to hundreds of (mostly free) APIs for developers to utilize, creating an account gives you a key that can be used to access data from different APIs on the platform. Awesome right?

Log on to RapidApi.com and search for 'Coinranking'. Then, subscribe to the free basic plan. The Coinranking API offers real-time cryptocurrency data of all major cryptocurrencies; these data range from their histories, to the current prices, market cap, and even exchanges.

5. Create the API request

Back to our cryptoApi.js file 🗃️, we have to create our request to fetch this real-time data from Coinranking (I'm proud of you).

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';


// our headers information
const cryptoApiHeaders = {

    'x-rapidapi-host': 'coinranking1.p.rapidapi.com',
    'x-rapidapi-key': 'b××××××××××××××××××××××××××××××'
}

const baseUrl = 'https://coinranking1.p.rapidapi.com';

const createRequest = (url) => ({ url, headers: cryptoApiHeaders });

export const cryptoApi = createApi({
  reducerPath: 'cryptoApi',
  baseQuery: fetchBaseQuery({ baseUrl }),
  endpoints: (builder) => ({
    getCryptos: builder.query({
      query: () => createRequest(`/coins`),
    })

First, we imported the createApi and fetchBaseQuery from the Redux Toolkit react package.

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

Secondly, we set the headers, which contain information about the request we are sending to the server, this 'headers' information comes from the Coinranking API. The variable consists of the host and your own API key. Simply copy your key from RapidApi.

// our headers information
const cryptoApiHeaders = {

    'x-rapidapi-host': 'coinranking1.p.rapidapi.com',
    'x-rapidapi-key': 'b××××××××××××××××××××××××××××××'
}

Exposing your API key on your codebase is a bad practice, later on, we will reference it as environment variables using the process.env object.

Thirdly, we created the variable to hold our base URL.

const baseUrl = 'https://coinranking1.p.rapidapi.com';

Afterward, the createApi() object was set up which contains some values inside of an object. These values include the:

  • reducerPath— which we simply set as the name of the file
  • baseQuery— which contains the fetchBaseQuery() that references the base URL
  • the endpoints— this is an important aspect, without the endpoints, we cannot access our data. The endpoints enable us to define what part of the API data we are fetching. In this case, we are fetching the coins data, hence, we set our createRequest() value to '/coins' which would return every coin alongside its basic information.

The createRequest() function was created so we can pass the url and headers in our query request.

const createRequest = (url) => ({ url, headers: cryptoApiHeaders });

Halfway Recap 🥛

Let us recap what we have done so far.

We created a store in our app folder 📁, then we imported the store variable to our index.js to pass to it to a { Provider } which we imported from Redux.

Then we wrapped our app with the { Provider } object to enable all components to have access to the { Provider } and hence, the store.

Furthermore, we created our API file which would request data from the API server. Now we have to connect this API file to the store.

6. Connect API to the store

To add our API file to our Redux store, we will navigate back to the store.js file in our app folder, then import our cryptoApi.js file.

import { cryptoApi } from '../services/cryptoApi';

In the reducer object, we would have to specify the API file and use the reducer slice from Redux. Optionally, you could add the API middleware to cache your data requests so an API call does not have to be made every time.

export default configureStore({
  reducer: {
    //  add the generated reducer as a specific top-level slice
    [cryptoApi.reducerPath]: cryptoApi.reducer,
  },
  // adding the api middleware enables caching, invalidation, polling,
  // and other useful features of `rtk-query`.
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(cryptoApi.middleware),
})

Your store.js should look like this:

import { configureStore } from '@reduxjs/toolkit';

import { cryptoApi } from '../services/cryptoApi';

export default configureStore({
    reducer: {
        [cryptoApi.reducerPath]: cryptoApi.reducer,
    },
middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(cryptoApi.middleware),
     }),
})

If you're adding additional APIs, you just need to create a new reducer object and specify the path. Easy!

7. Export the Query Hook

Now that our app is connected to the API, we have to export the data fetched from API using a Redux Toolkit hook called useGetCryptosQuery in this case.

When we head back to our cryptoApi.js file, it should look something like this:

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';


// our headers information
const cryptoApiHeaders = {

    'x-rapidapi-host': 'coinranking1.p.rapidapi.com',
    'x-rapidapi-key': 'b××××××××××××××××××××××××××××××'
}

const baseUrl = 'https://coinranking1.p.rapidapi.com';

const createRequest = (url) => ({ url, headers: cryptoApiHeaders });

export const cryptoApi = createApi({
  reducerPath: 'cryptoApi',
  baseQuery: fetchBaseQuery({ baseUrl }),
  endpoints: (builder) => ({
    getCryptos: builder.query({
      query: () => createRequest(`/coins`),
    })

We have to export the data gotten via a hook, the name of the hook is based on defined endpoints, with a 'use' and 'query' attached as prefix and suffix respectively. In this case, the name of our exported hook will be useGetCryptosQuery.

// Export hooks for usage in functional components, which are
// auto-generated based on the defined endpoints
export const { useGetCryptosQuery } = cryptoApi

Fetching API Data

Awesome job so far 👍. At this stage, we can now fetch out data from the Coinranking API.

1. Create a Component or Page

We will create a component in an src/components directory called Home.js. Afterward, we will create a functional component where we can render the data we get from the API.

2. Import the useGetCryptosQuery hook

At the top of the page, import the hook we exported from the cryptoApi.js file.

// Home.js

import React from 'react'


// import the hook
import { useGetCryptosQuery } from '../services/cryptoApi';

const Home = () => {
            return(
                  <div> </div>
                      )
        }

3. Get the data using hooks

We are obtaining the data from the API using hooks imported earlier. We simply create a hook containing some variables; data which is the data to be obtained from the API and other variables or states such as isLoading, error can be added as well.

const { data, isLoading } = useGetCryptosQuery;

Using the query Hook automatically fetches the data from the API and returns the query values. All we simply need to do is to render these data in a human-readable format. However, just to confirm that our request was successful, we can simply console.log the data on our browser console.

const { data, isLoading } = useGetCryptosQuery;
console.log(data)

4. Rendering the Data

If your request was successful, you would see a response from the API in JSON format, this allows you to know the structure in which the information on the API is being returned and how you can access it.

There are many ways to render the data, but to make it easy for you, simply create a variable containing the query you want to create. This allows you to create reusable code which you can render at any part of your application.

// for rendering coin statistics
const yourVarName = data?.data?.stats

// for rendering coin info
const anotherVarName = data?.data?.coins

To render something out:

 // Home.js

import React from 'react'


 // import the hook
import { useGetCryptosQuery } from '../services/cryptoApi';

const Home = () => {
       const { data, isLoading } = useGetCryptosQuery;
console.log(data)


  // for rendering coin statistics
const yourVarName = data?.data?.stats

 // for rendering coin info
const anotherVarName = data?.data?.coins

            return(
                  <div>
                     <h1> Total Cryptocurrencies Available</h1>
                                 {yourVarName.total}
                  </div>
                   <div>
                         <h1> Currency Name </h1>
                                 {anotherVarName.name}
                   </div>
                      )
        }

Warning ⚠️: Never expose your API key publicly in your code, simply reference it as an environment variable, you can check this link on how to do this.

Redux Toolkit provides an easier way to make API calls to a server, to get additional data, all you need to do is to keep adding endpoints.

If you finished this article, congratulations and I'm proud of you! APIs have certainly become the bedrock of software development, we are at that point in time where information is as cheap as air. Therefore, knowledge of accessing and spreading this information/data is invaluable.

I hope this article helped you become comfortable with Redux Toolkit which is now the officially recommended package for writing Redux logic. A link to the official Redux Toolkit documentation is attached below.

Kindly follow me on Twitter.

Until we meet again, happy coding!

Attributions

  • Redux Toolkit Official Docs ➡️ HERE
  • Redux Toolkit GitHub Repo ➡️ HERE
  • RapidApi ➡️ HERE
  • Understanding APIs ➡️ HERE