• 中文
  • ENGLISH
redux 中action以及reducer的初步介绍
2016/04/01

前言

最近React的出现风靡了几乎集团整个前端圈,优雅的实现了web Component,同时还有React-native的发布确实让我们没有理由不去学习一把react。但是于angular不同,react被吹的天花乱坠也始终是一个UI层面的解决方案,如何让React也能够成为一个体系,至少数据流的管理是必不可少的。facebook之前提出了flux单向数据流的概念(这个概念不限于前端,在iOS以及android开发中也同样有实践)。而我们今天要讨论的便是flux的一个实现--redux中的管理数据流的模块。

redux的是facebook提出的flux框架的一个优秀的实现(虽然说使用过程中还是有不少弊端,但是相比于flux来说的确有了优化,所以在react下的flux架构的实现建议使用redux-react)。redux工作流程是什么呢?往下看


redux 工作流程示意图

//待补充

大家可以通过这张流程图发现,在redux(flux单向数据流)中用户的操作并不会直接导致view层的更新,而是view层发出actions通知出发store里的reducer从而来更新state;state的改变会将更新反馈给我们的view层,从而让我们的view层发生相应的反应给用户。

在这篇文章中,我们刨去state的绑定,不说view如何依据数据的改变而刷新,只聚焦于中间数据更新的两个重要模块,action 以及 reducer

action

react给我们提供了一个virtual DOM(一个虚拟DOM对象,也是react之所以在性能上优越的一个重要的点),那么作为一个web应用至少需要又一个数据结构,来让整个应用的数据结构状态更新的来源更加丰富。如果我们将我们的reducer比作我们最终对于数据处理的功能模块,那么action就是对于我们获取到的数据的时的一个预处理功能模块。在我们的web应用中,所有的数据与状态的变化几乎都来源于事件,任何的事件都可能产生需要合并到全局数据对象里的新数据或者线索。但是action与event并不等同,因为并不会所有的event都会出发action,而我们只需要将我们感兴趣的部分传入action函数即可。

action在上面介绍到,仅仅是作为与处理模块,将脏数据筛选掉,它未必产生了可以直接合并到全局对象的数据与结构,它甚至可能只是提供了线索,表示「需要获取某某数据,但不在我这儿」。action 函数的设计,也为它「只提供线索」的做法提供了支持,action 函数必须返回一个带有 type 属性的 plain object

//actions.js
//添加 item 只需要一个 text 字符串数据
export function addItem(text) {
return {
type: 'ADD_ITEM',
text
}
}
//删除 item 只需要拿到它的 id
export function deleteItem(id) {
return {
type: 'DELETE_ITEM',
id
}
}

//删除所有已完成事项,不需要额外数据,只需要线索,线索就是 type
export function clearCompleted() {
return {
type: 'CLEAR_COMPLETED'
}
}

如上所示,action 函数的设计理念如下:

  • action 的参数用来筛掉脏数据,调用 action 函数的人,有义务只传入它需要的数据
  • action 返回的 plain object 中包含属性为 type 的常量值
  • 表明这个对象里携带的其他数据应该被如何「再处理」
  • 或者不带其他数据,仅仅启示已有数据需要如何调整,或者需要主动获取哪些数据

reducer

reducer 就是迎接 action 函数返回的线索的「数据再处理函数」, action 是「预处理函数」。

因为 action 返回的数据有个固定的结构,所以 reducer 函数也有个固定结构。

//reducer 接受两个参数,全局数据对象 state 以及 action 函数返回的 action 对象
//返回新的全局数据对象 new state
export default (state, action) => {
switch (action.type) {
case A:
return handleA(state)
case B:
return handleB(state)
case C:
return handleC(state)
default:
return state //如果没有匹配上就直接返回原 state
}
}

如上所示,每个 action.type 的 case (A/B/C),都有一个专门对应的数据处理函数 (handleA/handleB/handleC),处理完之后返回新的 state 即可。

reducer 只是一个模式匹配的东西,真正处理数据的函数,是额外在别的地方写的,在 reducer 中调用罢了。

reducer 为什么叫 reducer 呢?因为 action 对象各种各样,每种对应某个 case ,但最后都汇总到 state 对象中,从多到一,这是一个减少( reduce )的过程,所以完成这个过程的函数叫 reducer。

大家对于action和reducer的概念是否有了一定的了解了呢?总的来说合理的使用action和reducer会让你的工程代码更加的明了以及易于维护。那么redux玩起来吧

订阅我们