我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

最近几个月在看的几个代码,貌似都有类似的设计模式的概念体现,典型的代表就是redux里面,每条数据都有typepayload,当然也有其它特征。目前,苏南大叔还不知道这种代码设计模式的名字。所以,暂时就是对这种类似的思想进行一下简要的描述。

苏南大叔:一个代码设计模式的实现,action/reducer/dispatch - react数据设计模式
一个代码设计模式的实现,action/reducer/dispatch(图8-1)

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文简要描述一个最近经常看到的代码设计模式。测试环境:create-react-app@5.0.1react@18.2.0react-dom@18.2.0node@16.14.2

本文的测试代码,主要来着下面这个react@18todos应用。为了文章说明方便,部分代码略有修改。仓库地址如下:

定义数据

这里定义一个todos数据,以及一个setTodos的函数,用于修改todos数据。

// 一定放在dispatch前面
const storeState = {
    todos: [
        { id: 695, text: '苏南大叔的日程1' },
        { id: 696, text: '苏南大叔的日程2' },
        { id: 697, text: '苏南大叔的日程3' }
    ]
};
const setTodos = (todos) => {
    storeState.todos = todos;
    console.log(storeState.todos);
}

苏南大叔:一个代码设计模式的实现,action/reducer/dispatch - 数据定义
一个代码设计模式的实现,action/reducer/dispatch(图8-2)

定义reducer

function combineReducers(reducers) {
    return function reducer(state, action) {
        const changed = {};
        for (let key in reducers) {
            changed[key] = reducers[key](state[key], action);
        }
        return {
            ...state,
            ...changed,
        }
    };
}
const reducers = {
    todos(prevState, action) {
        const { type, payload } = action;
        switch (type) {
            case 'add':
                if (!prevState.find(todo => todo.text === payload.text)) {
                    return [...prevState, payload];
                }
                return prevState;
            case 'remove':
                return prevState.filter(todo => {
                    return todo.text !== payload.text;
                });
            default:
        }
        return prevState;
    },
};
const reducer = combineReducers(reducers);

苏南大叔:一个代码设计模式的实现,action/reducer/dispatch - reducers
一个代码设计模式的实现,action/reducer/dispatch(图8-3)

苏南大叔:一个代码设计模式的实现,action/reducer/dispatch - reducers-2
一个代码设计模式的实现,action/reducer/dispatch(图8-4)

定义dispatch

const dispatch = (action) => {
    const setters = {
        todos: setTodos,
    }
    const newState = reducer(storeState, action);
    for (let key in newState) {
        setters[key](newState[key]);
    }
};

苏南大叔:一个代码设计模式的实现,action/reducer/dispatch - dispatch
一个代码设计模式的实现,action/reducer/dispatch(图8-5)

定义action

function createAdd(text) {
    return {
        type: 'add',
        payload: {
            id: parseInt(Date.now().toString().slice(-3)),
            text,
        },
    }
}
function createRemove(text) {
    return {
        type: 'remove',
        payload:{
            text
        }
    };
}

苏南大叔:一个代码设计模式的实现,action/reducer/dispatch - action
一个代码设计模式的实现,action/reducer/dispatch(图8-6)

绑定dispatchaction

function bindActionCreators(actionCreators, dispatch) {
    const ret = {};
    for (let key in actionCreators) {
        ret[key] = function (...args) {
            const actionCreator = actionCreators[key];
            const action = actionCreator(...args);
            dispatch(action);
        };
    }
    return ret;
}

苏南大叔:一个代码设计模式的实现,action/reducer/dispatch - bind
一个代码设计模式的实现,action/reducer/dispatch(图8-7)

调用

const obj = bindActionCreators({ addTodo: createAdd, removeTodo: createRemove }, dispatch);
obj.addTodo("苏南大叔在北京的行程");
obj.addTodo("苏南大叔在唐山的行程");
obj.removeTodo("苏南大叔的日程2");

苏南大叔:一个代码设计模式的实现,action/reducer/dispatch - 运行结果
一个代码设计模式的实现,action/reducer/dispatch(图8-8)

变量示例

这里设计了很多概念,先做个概念示例。

变量名字value
typeadd
payload{text:text}
action{type:'add',payload:{text}}
setters{todos:(todos)=>{}}
actionCreater{addTodo:()=>{return {type:'add',payload:{text}};}}
reducers{todos(state, action) {}}
reducercombineReducers(reducers)
dispatch
objbindActionCreators(actionCreators, dispatch)

目前苏南大叔的理解是:

目标操作数据的样子就是:{type:'add',payload:{text}}
action的样子就是:return 目标数据
reducers就是:定义逻辑,根据目标数据的type来操作目标数据的过滤和合并
dispatch就是:执行reducers定义的逻辑
obj就是形成了一个具有各自操作功能的类。

相关链接

这个todosgithub仓库,个人觉得本来挺简单的需求,咋写的这么这么复杂的数据处理逻辑呢?而且这种写法的数据处理类似逻辑,至少在不同的项目里面,看到三次以上了。所以...........这是个设计模式不是?哈哈哈。

这个项目的其它react传统逻辑,请参考下面的链接,这里就不一一描述了。

结束语

更多react相关经验文章,请点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   react