第47节——使用bindActionCreators封装actions模块

一、什么是action creators

1、概念

在Redux中,Action Creators是一种函数,它用于创建一个描述应用程序状态变化的action对象。Action对象是一个普通JavaScript对象,它包含一个描述action类型的字符串属性(通常称为"type"),以及与该操作相关的其他属性。

Action Creators 是 Redux 应用程序的重要部分,因为它们提供了一种清晰和标准化的方式来描述应用程序中的操作,并将这些操作转化为 Redux 可以理解的形式。此外,Action Creators 还允许应用程序的各个部分之间进行通信,包括 React 组件和 Redux Store。

2、例子

一下部分就是一个简单的action creators

jsx 复制代码
function incrementCounter() {
  return { 
    type: 'INCREMENT_COUNTER' 
  };
}

二、什么是bindActionCreators

1、概念

bindActionCreators 是 Redux 中的一个函数,用于将多个 action creators 绑定到 dispatch 函数上,使得可以在 Redux 应用中轻松调用这些 action creators。

2、基本语法

jsx 复制代码
/**
 * 接收两个参数
 * 第一个参数 actionCreators:一个 Action Creator 函数或包含多个 Action Creator 函数的对象。
 * 如果是对象,则对象的键名将用作 Action Creator 函数的名称。
 * dispatch:Redux Store 的 dispatch 函数。
 * 
 * bindActionCreators 的返回值是一个对象,
 * 这个对象包含了与原始 action creators 同名的函数,
 * 但这些函数在调用时会自动派发一个 action,而不需要手动调用 dispatch。
 * 这个返回的对象可以直接作为组件的 props 传递给 React 组件使用
 */
const actions = bindActionCreators({ incrementCounter }, dispatch);

三、封装一个userActions hooks

将多个 Action Creator 函数绑定到 Redux store 的 dispatch 函数上,使它们能够被在组件中直接调用。

jsx 复制代码
import { useMemo } from "react";
import { useDispatch } from "react-redux";
import { bindActionCreators } from "redux";

/**
 *
 * @param {} actionCreators
 * 接收一个actionCreators对象
 * @returns
 */
export const useAction = (actionCreators) => {
  const dispatch = useDispatch();
  return bindActionCreators(actionCreators, dispatch);
};

// 进阶使用useMemo
// export const useAction = (actionCreators) => {
//   const dispatch = useDispatch();
//   return useMemo(() => {
//     console.log("调用了");
//     return bindActionCreators(actionCreators, dispatch);
//   }, [actionCreators, dispatch]);
// };

四、基本使用

1、创建actions目录,并在目录里创建user.js模块

jsx 复制代码
import { bindActionCreators } from "redux";
import { useDispatch } from "react-redux";

function addAge() {
  return {
    type: "user/addAge",
  };
}

export default {
  addAge,
};

2、在reducer模块中添加user.js模块

jsx 复制代码
import produce from "immer";

const defaultState = {
  name: "李光明",
  age: 20,
};

export const userReducer = (state = defaultState, action) => {
  switch (action.type) {
    /**
     * reducer模块化后命名
     * 一般要求全局唯一
     * 一般来可以采用模块名/case名的方式
     */
    case "user/addAge":
      // 如果使用了之间封装的immer中间件则必须使用immer更新
      // return produce(state, draft => {
      //   draft.age += 1
      // })
      return {...state, age: state.age + 1}
    default:
      return state;
  }
};

3、页面中使用

jsx 复制代码
import { useSelector } from "react-redux";
import { useAction } from "./store/utils";
import userActionCreators from "./store/actions/user";
import { compose } from "redux";

export default function LearnRedux3() {
  const state = useSelector((state) => state.user);

  /**
   * 所以的action最终都要使用dispath分发
   * 那么我就使用直接把action creator 和 dispath绑定
   * 在页面中直接使用
   */
  const action = useAction(userActionCreators);
  const add = () => {
    console.log(action);
    action.addAge();
  };

  return (
    <div>
      <div>年龄:{state.age}</div>
      <button onClick={() => add()}>过年</button>
    </div>
  );
}
相关推荐
程序员黑豆2 小时前
Java类型推断完全指南:从var到菱形运算符,掌握使用限制与最佳实践
java·前端·ai编程
To_OC2 小时前
踩了个 TS 的坑之后,我终于把 type 和 interface 掰明白了
前端·react.js·typescript
GreenTea2 小时前
深度解读 Anthropic 多智能体报告:更强的模型 ≠ 更好的协调
前端·后端·算法
浮生望3 小时前
前端API工程化:用 Mock 数据与 Axios 配置实现独立于后端的并行开发
前端
万少3 小时前
给 DeepSeek Harness 装个"应用商店":一条命令,595 个插件随你逛
前端·javascript·后端
波波0073 小时前
C# 15 重磅新特性: 带标签 break 与 continue:重新定义嵌套循环控制流
服务器·前端·c#
Brown.alexis4 小时前
es6知识点1-自备使用
前端·ecmascript·es6
小爬的老粉丝5 小时前
JavaScript 纯前端预览 WPS:先识别容器,再路由解析器
前端·javascript·wps
计算机魔术师6 小时前
新兴多智能体系统的模式与问题
前端
用户059540174466 小时前
AI Agent 上下文污染踩坑实录:用 pytest + Redis 揪出 3 类记忆串号 bug,排查 6 小时
前端·css