You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Redux中多dispatch仅最后一个生效问题求助

React Redux中多次dispatch仅最后一个生效的问题解决

问题现象

在React Redux项目的action中连续调用两个dispatch时,始终只有最后一个dispatch的效果生效。调换两个dispatch的顺序后,依然是最后一个生效。

代码示例

示例1:仅最后一个SET_BLOGS的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: 'UPDATE_PAGE', payload: {
          currentPage: responseAPI.current_page, 
          totalPage: responseAPI.total_page
        }}) // 此dispatch不生效

        dispatch({type: 'SET_BLOGS', payload: responseAPI.data}) // 仅此生效
        
    })
    .catch(error => {
        console.log('error',error);
    })
  }
}
export default setDataBlog

示例2:调换顺序后,仅最后一个UPDATE_PAGE的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}) // 此dispatch不生效
        dispatch({type: 'UPDATE_PAGE', payload: {
          currentPage: responseAPI.current_page, 
          totalPage: responseAPI.total_page
        }}) // 仅此生效

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

Home组件调用action代码

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();

  // 检查是否生效
  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;

问题原因及解决方法

核心原因

这种问题几乎都是reducer的写法不符合Redux要求导致的:

  1. 直接修改原state对象,而非返回新的状态对象,Redux无法检测到状态变化;
  2. 返回新状态时没有合并原state的其他属性,导致前一个dispatch的状态被后一个覆盖。

错误的reducer示例(导致问题的写法)

const initialState = {
  dataBlog: [],
  page: { currentPage: 1, totalPage: 1 }
};

// 错误写法1:直接修改原state
function homeReducer(state = initialState, action) {
  switch(action.type) {
    case 'UPDATE_PAGE':
      state.page = action.payload; // 直接修改原state,Redux不识别状态变化
      return state;
    case 'SET_BLOGS':
      state.dataBlog = action.payload; // 同样直接修改原state
      return state;
    default:
      return state;
  }
}

// 错误写法2:返回时未合并原state,覆盖整个状态
function homeReducer(state = initialState, action) {
  switch(action.type) {
    case 'UPDATE_PAGE':
      return action.payload; // 直接返回payload,丢失dataBlog
    case 'SET_BLOGS':
      return { dataBlog: action.payload }; // 丢失page属性
    default:
      return state;
  }
}

正确的reducer写法

必须返回新的状态对象,且通过展开运算符合并原state的所有属性,只修改需要更新的部分:

const initialState = {
  dataBlog: [],
  page: { currentPage: 1, totalPage: 1 }
};

function homeReducer(state = initialState, action) {
  switch(action.type) {
    case 'UPDATE_PAGE':
      return {
        ...state, // 展开原state,保留dataBlog等其他属性
        page: action.payload
      };
    case 'SET_BLOGS':
      return {
        ...state, // 保留page等其他属性
        dataBlog: action.payload
      };
    default:
      return state;
  }
}

验证方法

修改reducer后,重新运行项目,查看组件中的console.log('page', page)是否能正确打印更新后的页码,同时dataBlog也能正常渲染。

内容的提问来源于stack exchange,提问作者Dwi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:06:23