Hi, Today we are going to build simple React application which call the get request and show the data. We are using Redux for this application, Redux is a state management library for javascript applications. If you are not familiar with Redux, I highly recommend you to read the Redux fundamentals from Redux documentation. For better understanding watch the demo video.
So let's start coding...
Demo Video
Source Code
Project Structure
Create React App
$ npx create-react-app react-redux-api
$ cd react-redux-api
$ npm start
Install Dependencies
Redux : It's a State management library for javascript applications.
Axios : It's a promise-based HTTP client that supports an easy-to-use API.
React-Redux : React Redux is the official React Ui bindings layer for Redux.
@reduxjs/toolkit : For writing clean redux code and it comes with most widly used Redux addons.
Create API Actions
src/store/api.js
import { createAction } from "@reduxjs/toolkit";
export const apiCallBegan = createAction("api/callBegan");
export const apiCallSucess = createAction("api/callSuccess");
export const apiCallFailed = createAction("api/callFailed");
Create API Middleware
src/store/middleware/api.js
import axios from "axios";
import * as actions from "../api";
const api =
({ dispatch }) =>
(next) =>
async (action) => {
if (action.type !== actions.apiCallBegan.type) return next(action);
const { url, method, data, onStart, onSuccess, onError } =
action.payload;
if (onStart) dispatch({ type: onStart });
next(action);
try {
const response = await axios.request({
baseURL: "https://jsonplaceholder.typicode.com",
url,
method,
data,
});
// General
dispatch(actions.apiCallSucess(response.data));
// Specific
if (onSuccess)
dispatch({ type: onSuccess, payload: response.data });
} catch (error) {
// General
dispatch(actions.apiCallFailed(error.message));
// Specific
if (onError) dispatch({ type: onError, payload: error.message });
}
};
export default api;
Redux already has an async middleware function called Redux "Thunk" middleware. The thunk middleware allows us to write functions that get dispatch and getState as arguments. For better understanding read documentation.
Create Actions & Reducers for Posts
src/store/posts.js
import { createSlice } from "@reduxjs/toolkit";
import { apiCallBegan } from "./api";
const slice = createSlice({
name: "posts",
initialState: {
list: [],
loading: false,
},
reducers: {
postsRequested: (posts, action) => {
posts.loading = true;
},
postsReceived: (posts, action) => {
posts.list = action.payload;
posts.loading = false;
},
postsRequestFailed: (posts, action) => {
posts.loading = false;
},
},
});
export default slice.reducer;
const { postsRequested, postsReceived, postsRequestFailed } = slice.actions;
const url = "/posts";
export const loadposts = () => (dispatch) => {
return dispatch(
apiCallBegan({
url,
onStart: postsRequested.type,
onSuccess: postsReceived.type,
onError: postsRequestFailed.type,
})
);
};
Configure Store
import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit";
import reducer from "./posts";
import api from "./middleware/api";
export default function store() {
return configureStore({
reducer,
middleware: [...getDefaultMiddleware(), api],
});
}
Posts Component
src/components/posts.js
import { useDispatch, useSelector } from "react-redux";
import { loadposts } from "../store/posts";
import { useEffect } from "react";
const Posts = () => {
const dispatch = useDispatch();
const posts = useSelector((state) => state.list);
useEffect(() => {
dispatch(loadposts());
}, [dispatch]);
return (
<div>
<h1>Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
};
export default Posts;
App.js
import { Provider } from "react-redux";
import configureStore from "./store/configureStore";
import Posts from "./components/posts";
import "./App.css";
const store = configureStore();
const App = () => {
return (
<Provider store={store}>
<Posts />
</Provider>
);
};
export default App;
That's it, run the project on your local server. check APIs are working or not. If you found any mistakes or making code better please let me know. I hope you have learned something.
If you like this post, support me on my youtube channel it inspire me a lot.
Thank You...
Top comments (3)
thank you for this article, I really appreciate it. Just a question, I wanna change the url endpoint. I'm using a restaurant menu app and I want the url to be changed every time a user click on a plate(eg: pizzas or burgers). I have a component that have the menu list.
Hey, I dont seem to be getting any errors but it just comes up as a blank app in my browser.
I uploaded it in an image and in the configureStore.js the getDefaultMiddleware is crossed out not sure if this has anything to do with it but seems like the only thing not working.
It was deprecated. Instead of importing it from "@reduxjs/toolkit" and setting it to the array like that, type your configureStore as:
return configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(api),
})