An Easy Way to Make API Calls: Redux Toolkit
Fetch API data easily on your React App
Table of contents
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!