首先呢~ 在分享前先贴上我写的redux-chef源码,你们若有兴趣能够阅读:redux-chefgit
在使用redux好久之后,有一天写着写着,忽然以为actions/constants/reducers这一套东西显得十分啰嗦(相信不少同窗有这种感受)github
好比看redux的官方实例: todomvc。简简单单一个todomvc,也写出来很多样板代码。redux
哎呀好麻烦吶,我就想简简单单调用改个数据流而已,为啥要我写这么这么长的代码?mvc
因而乎!听闻社区里的那个 dva 很强大,我点开官网看了看它的示例,受其启发,忍不住也花了几个小时写了一个 redux-chef(不过自己和dva没什么关系,类似的地方也就只有model的设计了)来完成我优雅修改redux数据流的设想~app
那么日常的redux,除了上述说的代码样板比较多以外,还有一个点也是修改同一个数据,须要跳跃好几个文件,这也是蛮费心力的,我的感受!框架
通常来讲,一个reducer关注的每每只是其维护的state
。那么其实能够把每一个reducer维护的state、以及其全部的action维护在同一个model里面诶dom
首先根据业务场景定义本身的model(为了节省空间,代码省略了一部分),而后用redux-chef导出的kitchen煮一下(笑)。这样的models数据就是通过主厨精心加工过的,能够以后在业务代码里优雅调用了~函数
// models/index.ts
import { kitchen } from '../redux-chef';
const Cord = {
namespace: 'cord',
state: { x: 3, y: 4 },
action: {
update(x: number, y: number) {
return { x, y };
},
setDoubleX: () => (state: any) => {
return {
...state,
x: state.x * 2
}
}
},
reducer: function (state: any, action: any) {
//...
}
};
const Points = {
namespace: 'points',
state: [],
reducer: function (state: any, action: any) {
//...
}
};
export default kitchen({ Cord, Points });
复制代码
备注:完整示例models代码 -> github.com/soulizs/red…优化
而后在将这些加工后的models应用到咱们用redux建立的store里,就能够开始在应用代码里redux-chef设计的调用啦!spa
示例使用redux-chef后的数据流调用方式以下:
// App.ts
import models from './models/index.ts';
function updateCord() {
models.Cord.update(generateRandNum(), generateRandNum())
}
function setDoubleCordX() {
models.Cord.setDoubleX();
}
// render
<Button onClick={updateCord}>update cord x & y</Button>
<Button onClick={setDoubleCordX}>double cord x</Button>
复制代码
天呐,修改数据流只须要关注models里action函数,而后在应用里直接调用对应的model:models.Cord.setDoubleX();
就完成了数据流的改动,而后将对应的state进行connect,即完成了更新后数据的读取。
优雅的是,这种调用给应用开发者带来了流程的简化,只须要关注业务的开发,减小重复的样板代码~
备注:眼尖的同窗或许会发如今 Cord model里面的这两个actionupdate
,setDoubleX
有点不同。缘由是,setDoubleX因为须要读取model里的state,因此设计成高阶函数,用以自动读取其对应model的state!
固然这种方式也提供了使用咱们自定义使用action的自由,在model.reducer会进行分发。以下示例代码:
// actions/index.ts
import { dispatch } from '../redux-chef';
export function setCordX(x: number) {
dispatch({
type: constants.SET_CORD_X, x
});
}
// App.ts
import { setCordX } from './actions/index.ts';
// render
<Button onClick={() => setCordX(generateRandNum())}>set cord x</Button>
复制代码
新旧共存,毛问题~
好了使用方式上文都介绍了,其实redux-chef的设计也挺简单的,主要是Chef(), dispatch(), cook(), kitchen(), Chef.apply()
这四个API,有兴趣的同窗阅读一下源码便可(也不长)。
简单来讲:
models.Cord.setDoubleX();
,会使用内部自定义的@@${__CHEF_INTERNAL_TYPE__}(${name})
分发事件,本质上仍是分发。上文提到的,若是model.action须要使用自己的state做为依赖计算的话,利用高阶函数自动传入state。
没什么问题是不能用多一层抽象解决的!
谢谢你们的阅读!固然还有不少优化和设计的空间,你们若是有想法与建议,欢迎评论~
(为何起这个名字 redux-chef?由于我常常在半夜敲代码时感到饥饿...)