一、什么是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>
);
}