Redux Thunk Middleware In Redux-Toolkit with async await

Redux Thunk Middleware In Redux-Toolkit with async await

Today we’ll learn how to use Redux Thunk middleware in Redux Toolkit with async await

You can read this article on Medium

source code live demo

So, we’ll learn how to use redux-thunk with an example. We’ll make the get request, fetch the data, and display the data using async await.

So first create the react-app

npx create-react-app redux-thunk        

Install react-redux and redux-toolkit

npm i react-redux

npm i @reduxjs/toolkit        

After that let's set up the store

Create a folder redux inside the src folder and create a file postSlice.js

No alt text provided for this image

Inside the postSlice,

Import

import { createSlice,createAsyncThunk } from "@reduxjs/toolkit";        

Initialize the state

const initialState = {
post:[],
error:'',
loading:false
}        

Define the reducer using createSlice

const postSlice = createSlice({
	  name: 'posts',
	  initialState,
	  reducers:{},
});        

Let’s export the reducer

export default postSlice.reducer
export const getPost = (state) => state.postReducer.post;
export const getLoading = (state) => state.postReducer.loading;        

Here we are defining the?getPost?and?getLoading?functions these returns the desired state. make sure you use the same name for (state) that you have used inside the store for the reducer.

Here I have used the postReducer and the same name for the store.

Create the store inside the src folder

No alt text provided for this image

Now, let’s move to the main logic

import { createSlice,createAsyncThunk } from "@reduxjs/toolkit";
	

	const GET_POST_URL= "https://jsonplaceholder.typicode.com/posts";
	

	const initialState = {
	  post:[],
	  error:'',
	  loading:false
	}
	

	// fetch the post
	export const fetchPosts = createAsyncThunk(
	  'posts/fetchPosts', // use the slice name
	  async () => {
	    const response = await fetch(GET_POST_URL)
	    const data = await response.json();
	    return data
	  }
	)
	

	const postSlice = createSlice({
	  name: 'posts',
	  initialState,
	  reducers:{},
	  extraReducers:(builder)=>{
	    builder
	    .addCase(fetchPosts.pending,(state)=>{
	      state.loading=true
	    })
	    .addCase(fetchPosts.fulfilled,(state,action)=>{
	      state.loading=false
	      state.post=action.payload
	    })
	    .addCase(fetchPosts.rejected,(state,action)=>{
	      state.loading=false
	      state.error=action.error.message
	    })
	  }
	});
	

	export default postSlice.reducer;
	export const getPost = (state) => state.postReducer.post;
	export const getLoading = (state) => state.postReducer.loading;        

Let’s break it down into simple steps

Create the function using createAsyncThunk

	// fetch the post
	export const fetchPosts = createAsyncThunk(
	  'posts/fetchPosts',// use the slice name
	  async () => {
	    const response = await fetch(GET_POST_URL)
	    const data = await response.json();
	    return data
	  }
	)        

createAsyncThunk?accepts three parameters: a string action?type?value, a?payloadCreator?callback, and an?options?object.

A string that will be used to generate additional Redux action type constants, representing the lifecycle of an async request:

For example, a?type?argument of?'post/fetchPosts'?will generate these action types:

  • pending:?'post/fetchPosts/pending'?promise pending
  • fulfilled:?'post/fetchPosts/fulfilled'?promise fulfilled
  • rejected:?'post/fetchPosts/rejected'?promise rejected

# Callback function

A callback function that should return a promise containing the result of some asynchronous logic.

Here are simply returning the data.

So while we are using thunk middleware so let’s define the extra reducer

# extraReducers

extraReducers?allows?createSlice?to respond to other action types besides the types it has generated.

	const postSlice = createSlice({
	  name: 'posts',
	  initialState,
	  reducers:{},
	  extraReducers:(builder)=>{
	    builder
	    .addCase(fetchPosts.pending,(state)=>{
	      state.loading=true
	    })
	    .addCase(fetchPosts.fulfilled,(state,action)=>{
	      state.loading=false
	      state.post=action.payload
	    })
	    .addCase(fetchPosts.rejected,(state,action)=>{
	      state.loading=false
	      state.error=action.error.message
	    })
	  }
	});        

# Builder: This builder notation is also the only way to add matcher reducers and default case reducers to your slice.

Here we have added three different cases:

  1. if fetchPosts.pending then set the loading true
  2. if fetchPosts.fulfilled then set the loading to false and post to the action.payload (we have returned the data in createAsynThunk).
  3. if fetchPosts.rejected then set the loading to false and set the error message to action.error.message

so let’s use these in our project to show the posts

No alt text provided for this image

Inside the postList.jsx we’ll show the posts

	import React, { useState,useEffect } from 'react';
	import {fetchPosts,getPost,getLoading} from '../redux/postSlice';
	import {useSelector,useDispatch} from 'react-redux'
	

	const PostList = () => {
	

	  const getPosts = useSelector(getPost);
	  const stateloading = useSelector(getLoading)
	  const dispatch = useDispatch()
	

	  useEffect(()=>{
	    dispatch(fetchPosts());
	  },[])
	  return (
	    <div className='post-wrapper'>
	      {
	        getPosts.map((post,index)=>(
	          <div className='single-post' key={index}>
	            <h4>{post.title}</h4>
	            <h6>{post.body}</h6>
	          </div>
	        ))
	      }
	    </div>
	  )
	}
	

	export default PostList;        

Here we have imported our fetchPosts , getPost, getLoading form the postSlice.

Let’s dispatch the function fetchPosts to make the request and get the data

if now you console the getPosts you will see the data

No alt text provided for this image

let’s map over the data and display it

return 
	   ( <div className='post-wrapper'>
	      {
	        getPosts.map((post,index)=>(
	          <div className='single-post' key={index}>
	            <h4>{post.title}</h4>
	            <h6>{post.body}</h6>
	          </div>
	        ))
	      }
	    </div>
	  )        

Hope you learn it ??

Happy coding!

want to give suggestions:-

find me on?LinkedIn?Medium

have a look at?my portfolio

Email me at nidhisharma639593@gmail.com

要查看或添加评论,请登录

Nidhi Sharma的更多文章

社区洞察

其他会员也浏览了