设计实现优雅修改redux数据流的一个库 - redux-chef

栏目: Ruby · 发布时间: 5年前

内容简介:首先呢~ 在分享前先贴上我写的redux-chef源码,大家如有兴趣可以阅读:在使用redux很久以后,有一天写着写着,突然觉得actions/constants/reducers这一套东西显得十分啰嗦(相信很多同学有这种感觉)比如看redux的官方实例:

首先呢~ 在分享前先贴上我写的redux-chef源码,大家如有兴趣可以阅读: redux-chef

背景:麻烦的redux社区规范

在使用redux很久以后,有一天写着写着,突然觉得actions/constants/reducers这一套东西显得十分啰嗦(相信很多同学有这种感觉)

比如看redux的官方实例: todomvc 。简简单单一个todomvc,也写出来不少样板代码。

哎呀好麻烦吶,我就想简简单单调用改个数据流而已,为啥要我写这么这么长的代码?

于是乎!听闻社区里的那个 dva 很强大,我点开官网看了看它的示例,受其启发,忍不住也花了几个小时写了一个 redux-chef (不过本身和dva没什么关系,相似的地方也就只有model的设计了)来完成我优雅修改redux数据流的设想~

什么有趣的东西?一个主厨(Chef)!

那么平常的redux,除了上述说的代码样板比较多之外,还有一个点也是修改同一个数据,需要跳跃好几个文件,这也是蛮费心力的,个人感觉!

一般来说,一个reducer关注的往往只是其维护的 state 。那么其实可以把每个reducer维护的state、以及其所有的action维护在同一个model里面诶

根据业务设计自己的model

首先根据业务场景定义自己的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设计的调用啦!

优雅又简易的调用方式

示例使用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里面的这两个action updatesetDoubleX 有点不一样。原因是,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的设计哲学

好了使用方式上文都介绍了,其实redux-chef的设计也挺简单的,主要是 Chef(), dispatch(), cook(), kitchen(), Chef.apply() 这四个API,有兴趣的同学阅读一下源码即可(也不长)。

简单来说:

  • 自动聚合所有models的reducer返回给store应用
  • 如果调用了model.action,也就是说是这种操作姿势的话, models.Cord.setDoubleX(); ,会使用内部自定义的 @@${__CHEF_INTERNAL_TYPE__}(${name}) 分发事件,本质上还是分发。
设计实现优雅修改redux数据流的一个库 - redux-chef
  • 上文提到的,如果model.action需要使用本身的state作为依赖计算的话,利用高阶函数自动传入state。

  • 没什么问题是不能用多一层抽象解决的!

小结

  1. 建议大家在看完此文后,拉下此仓库运行一下看看!请点击: redux-chef (注意是improve-reading分支)
  2. 不建议大家在生产环境使用redux-chef。由于社区里存在很多优秀的应用框架,比如 dva 等等。(备注:本人也只是纯粹随便敲敲而已,暂不发布,也不做维护~

谢谢大家的阅读!当然还有很多优化和设计的空间,大家如果有想法与建议,欢迎评论~

(为什么起这个名字 redux-chef ?因为我经常在半夜敲代码时感到饥饿...)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Applications (Hacking Exposed)

Web Applications (Hacking Exposed)

Joel Scambray、Mike Shema / McGraw-Hill Osborne Media / 2002-06-19 / USD 49.99

Get in-depth coverage of Web application platforms and their vulnerabilities, presented the same popular format as the international bestseller, Hacking Exposed. Covering hacking scenarios across diff......一起来看看 《Web Applications (Hacking Exposed)》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

MD5 加密
MD5 加密

MD5 加密工具