一个代码设计模式的实现,action/reducer/dispatch
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
最近几个月在看的几个代码,貌似都有类似的设计模式的概念体现,典型的代表就是redux
里面,每条数据都有type
和payload
,当然也有其它特征。目前,苏南大叔还不知道这种代码设计模式的名字。所以,暂时就是对这种类似的思想进行一下简要的描述。
大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文简要描述一个最近经常看到的代码设计模式。测试环境:create-react-app@5.0.1
,react@18.2.0
,react-dom@18.2.0
,node@16.14.2
。
本文的测试代码,主要来着下面这个react@18
的todos
应用。为了文章说明方便,部分代码略有修改。仓库地址如下:
定义数据
这里定义一个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);
}
定义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);
定义dispatch
const dispatch = (action) => {
const setters = {
todos: setTodos,
}
const newState = reducer(storeState, action);
for (let key in newState) {
setters[key](newState[key]);
}
};
定义action
function createAdd(text) {
return {
type: 'add',
payload: {
id: parseInt(Date.now().toString().slice(-3)),
text,
},
}
}
function createRemove(text) {
return {
type: 'remove',
payload:{
text
}
};
}
绑定dispatch
和action
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;
}
调用
const obj = bindActionCreators({ addTodo: createAdd, removeTodo: createRemove }, dispatch);
obj.addTodo("苏南大叔在北京的行程");
obj.addTodo("苏南大叔在唐山的行程");
obj.removeTodo("苏南大叔的日程2");
变量示例
这里设计了很多概念,先做个概念示例。
变量名字 | value |
---|---|
type | add |
payload | {text:text} |
action | {type:'add',payload:{text}} |
setters | {todos:(todos)=>{}} |
actionCreater | {addTodo:()=>{return {type:'add',payload:{text}};}} |
reducers | {todos(state, action) {}} |
reducer | combineReducers(reducers) |
dispatch | |
obj | bindActionCreators(actionCreators, dispatch) |
目前苏南大叔的理解是:
目标操作数据的样子就是:{type:'add',payload:{text}}
action
的样子就是:return 目标数据reducers
就是:定义逻辑,根据目标数据的type来操作目标数据的过滤和合并dispatch
就是:执行reducers
定义的逻辑obj
就是形成了一个具有各自操作功能的类。
相关链接
这个todos
的github
仓库,个人觉得本来挺简单的需求,咋写的这么这么复杂的数据处理逻辑呢?而且这种写法的数据处理类似逻辑,至少在不同的项目里面,看到三次以上了。所以...........这是个设计模式不是?哈哈哈。
这个项目的其它react
传统逻辑,请参考下面的链接,这里就不一一描述了。
- https://newsn.net/say/react-useref.html
- https://newsn.net/say/react-usestate.html
- https://newsn.net/say/react-usememo.html
- https://newsn.net/say/react-useeffect.html
- https://github.com/Emiliewu/TodoList_React18
结束语
更多react
相关经验文章,请点击:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。