react项目--redux封装
阅读原文时间:2023年07月09日阅读:1

index.ts

1 const store = {
2 state: {
3 num: 20,
4 },
5 actions: {
6 // 放同步的代码
7 add1(newState: { num: number }, action: { type: string }) {
8 // redux 异步写法有问题
9 // setTimeout(() => {
10 // newState.num++;
11 // }, 500);
12 newState.num++;
13 },
14 add2(newState: { num: number }, action: { type: string; value: number }) {
15 newState.num += action.value;
16 },
17 add3(newState: { num: number }, action: { type: string; value: number }) {
18 newState.num += action.value;
19 },
20 },
21 // 优化redux-thunk的异步写法 (模仿vuex)
22 asyncActions: {
23 asyncAdd1(dispatch: Function) {
24 setTimeout(() => {
25 dispatch({ type: "add1" });
26 }, 1000);
27 },
28 },
29
30 // 1 初始写法
31 // add1: "add1",
32 // add2: "add2",
33 // 2 名字同一管理
34 // actionNames: {
35 // add1: "add1",
36 // add2: "add2",
37 // },
38 // 3 优化
39 actionNames: {},
40 };
41 // 我们现在想做到actionNames自动生成。不用我每一次添加一个方法,
42 // 都要在actionNames手动添加键值对,这样很麻烦。
43
44 let actionNames = {};
45 /**
46 * actionNames有多少个键值对,取决于actions里有多少个函数,
47 * 遍历store.actions,给actionNames添加键值对
48 */
49 for (let key in store.actions) {
50 actionNames[key] = key;
51 }
52 store.actionNames = actionNames;
53
54 export default store;
55 // 封装的目的:最终是有利于我们的开发或者维护
56 // 封装的思路是:将来开发的时候只需要把数据写和方法写入到这个
57 // 状态文件中,例如:XxxxStatus/index.ts,而不需要再去操作其
58 // 他的文件。(我们往这个方向去封装)

reducer.ts:

import handleNum from "./index";
// 管理数据
// const defaultState = {
// // num: 20,
// // num: Numstatus.state.num // 数据一多要写很多次
// …handleNum.state // 解构的写法
// };

let reducer = (
state = { …handleNum.state }, // 直接解构
action: { type: string; value: number }
) => {
// 调用dispatch就会执行这里的代码
// console.log("初始化执行了reducer….");
// 深度复制
let newState = JSON.parse(JSON.stringify(state));

// switch的做法是拿action.type和case后面的每一个值进行对比,进行遍历
// 把case后面的值做成对象,actionsNames
// 1 原始写法
// switch (action.type) {
// case handleNum.add1:
// handleNum.actions[handleNum.add1](newState,action)
// break;
// case handleNum.add2:
// handleNum.actions[handleNum.add2](newState,action)
// break;
// default:
// break;
// }
// 2 [优化],上面的写法,我们在每添加一个方法,都要多写一个case
// 拿action.type和actionsNames每一个项进行对比,如果相等,就调用
// 模块名 actions[下标](newState,action)

for (let key in handleNum.actionNames) {
// key 是每一个键
// 判断是否相等
// if (action.type === "add1") {
if (action.type === handleNum.actionNames[key]) {
handleNum.actions[handleNum.actionNames[key]](newState, action);
break;
}
}
// 好处:每一次写一个方法,都不需要手动添加case
return newState;
};

export default reducer;