Search code examples
reactjsreduxreact-reduxredux-toolkit

Can't use multiple dispatch in react redux


I have a problem, so I am trying to put two or more "dispatch" in my application but I don't know why it is just working one dispatch that I put in last

import axios from "axios";

const setDataBlog = (page) =>{
return (dispatch) => {
    axios.get(`http://localhost:4000/api/blogs/?page=${page}&perPage=3`)
    .then(result => {
        const responseAPI = result.data
        dispatch({type: 'UPDATE_PAGE', payload: 
        {currentPage: responseAPI.current_page, 
        totalPage: responseAPI.total_page}}) // this is not working

        dispatch({type: 'SET_BLOGS', payload: responseAPI.data}) //just work in here
        
    })
    .catch(error => {
        console.log('error',error);
    })
}}
export default setDataBlog

but if I change the location of the dispatch

import axios from "axios";

const setDataBlog = (page) =>{
return (dispatch) => {
    axios.get(`http://localhost:4000/api/blogs/?page=${page}&perPage=3`)
    .then(result => {
        const responseAPI = result.data

        dispatch({type: 'SET_BLOGS', payload: responseAPI.data}) //not working
        dispatch({type: 'UPDATE_PAGE', payload: 
        {currentPage: responseAPI.current_page, 
        totalPage: responseAPI.total_page}}) // working

    })
    .catch(error => {
        console.log('error',error);
    })
}}
export default setDataBlog

I'm trying to use it here

import { useEffect} from "react";
import CardBlog from "../components/CardBlog";
import Pagination from "../components/Pagination";
import {useDispatch, useSelector} from 'react-redux'
import {setDataBlog} from '../redux/action'

const Home = () => {
const {dataBlog, page} = useSelector(state => state.homeReducer);
const dispatch = useDispatch();

//check working or not
console.log('page', page);

useEffect(() => {
    dispatch(setDataBlog(1))
}, [dispatch])
return ( 
    <div className="max-w-screen-xl mx-auto px-4 py-16 sm:px-6 lg:px-8">
        <div className=" md:grid md:grid-cols-2 lg:grid-cols-3">
            {dataBlog?.map(blog => (
                <CardBlog key={blog._id} image={`http://localhost:4000/${blog.image}`} 
                title={blog.title} 
                body={blog.body}
                author={blog.author}
                date={blog.createdAt}/>
            ))}
        </div>
        <div>
            <Pagination/>
        </div>
    </div>
 );

}

export default Home;

thanks, sorry for my bad English, but I hope you understand what I said


Solution

  • I can't tell you why your code is failing, but I'd like to offer some advice. Avoid firing multiple synchronous actions.

    Think of an action as representing single thing that has happened: often a user event such as a button click or key press, or in this case a network response.

    I recommend combining the two actions above into a single action, e.g.

    dispatch({
      type: 'BLOG_API_RESPONSE',
      payload: {
        currentPage: responseAPI.current_page,
        totalPages: responseAPI.total_page,
        data: responseAPI.data,
      },
    });
    

    You can hook into BLOG_API_RESPONSE at multiple places in your reducers. Actions to state updates don't have to be one-to-one. One action can produce many state updates.

    You'll find your code easier to rationalise and debug when you restrict yourself to firing single synchronous actions.