Redux中的reducer到底是什么,以及它为什么叫reducer?
https://zhuanlan.zhihu.com/p/25863768
Redux有3大核心概念:
- Action
- Reducer
- Store
其中Action和Store都非常好理解,我们可以直接按照其字面意思,将他们理解为动作和储存。
Action表示应用中的各类动作或操作,不同的操作会改变应用相应的state状态,说白了就是一个带type属性的对象。
Store则是我们储存state的地方。我们通过redux当中的createStore方法来创建一个store,它提供3个主要的方法,在这里我们可以模拟一下createStore的源码:
// 以下代码示例来自redux官方教程
const createStore = (reducer) => {let state;let listeners = [];// 用来返回当前的stateconst getState = () => state;// 根据action调用reducer返回新的state并触发listenerconst dispatch = (action) => {state = reducer(state, action);listeners.forEach(listener => listener());};/* 这里的subscribe有两个功能
* 调用 subscribe(listener) 会使用listeners.push(listener)注册一个listener
* 而调用 subscribe 的返回函数则会注销掉listener
*/const subscribe = (listener) => {listeners.push(listener);return () => {listeners = listeners.filter(l => l !== listener);};};return { getState, dispatch, subscribe };
};
那么剩下的这个reducer连翻译都很难翻译的东西应该怎么理解呢?
我们注意到redux的官方文档里专门有一句对reducer命名的解释:
It's called a reducer because it's the type of function you would pass to Array.prototype.reduce(reducer, ?initialValue)
中文版的文档把这一句话翻译成了:
之所以称作 reducer 是因为它将被传递给 Array.prototype.reduce(reducer, ?initialValue) 方法。
我们要注意到这里的中文翻译理解其实是错误的。原文的本意并不是说redux里的reducer会被传入到 Array.prototype.reduce 这个方法中。真的要翻译的话,应该翻译为:
之所以将这样的函数称之为reducer,是因为这种函数与被传入 Array.prototype.reduce(reducer, ?initialValue) 的回调函数属于相同的类型。
为什么这么讲呢?我们来看一下array使用reduce方法的具体例子:
// 以下代码示例来自 MDN JavaScript 文档/* 这里的callback是和reducer非常相似的函数
* arr.reduce(callback, [initialValue])
*/var sum = [0, 1, 2, 3].reduce(function(acc, val) {return acc + val;
}, 0);
// sum = 6/* 注意这当中的回调函数 (prev, curr) => prev + curr
* 与我们redux当中的reducer模型 (previousState, action) => newState 看起来是不是非常相似呢
*/
[0, 1, 2, 3, 4].reduce( (prev, curr) => prev + curr );
我们再来看一个简单的具体的reducer的例子:
// 以下代码示例来自redux官方教程// reducer接受state和action并返回新的state
const todos = (state = [], action) => {// 根据不同的action.type对state进行不同的操作,一般都是用switch语句来实现,当然你要用if...else我也拦不住你switch (action.type) {case 'ADD_TODO':return [// 这里是ES7里的对象展开运算符语法...state,{id: action.id,text: action.text,completed: false}];// 不知道是什么action类型的话则返回默认statedefault:return state;}
};
如果非要翻译reducer的话,可以将其翻译为缩减器或者折叠器?
为了进一步加深理解,我们再了解一下reduce是什么东西,这个名词其实是函数式编程当中的一个术语,在更多的情况下,reduce操作被称为Fold折叠(下图来自维基百科)。
直观起见,我们还是拿JavaScript来理解。reduce属于一种高阶函数,它将其中的回调函数reducer递归应用到数组的所有元素上并返回一个独立的值。这也就是“缩减”或“折叠”的意义所在了。
总而言之一句话,redux当中的reducer之所以叫做reducer,是因为它和 Array.prototype.reduce 当中传入的回调函数非常相似。
当然,如果你认为这种命名不完美容易产生歧义,你完全可以去给redux提交一个PR,提供一种更加恰当的命名方式。
有任何好的意见或者是建议欢迎在评论区参与讨论,如果文中有任何错误也欢迎在评论区批评指正。
参考资料
- Why is a Redux reducer called a reducer?
- Reducers
- Reducer 中文文档
- Array.prototype.reduce()
- Fold (higher-order function)
你也可以加入本专栏QQ群一起交流学习。QQ群号码:591950591
更加欢迎将你的原创或翻译文章投稿至本专栏。
Redux中的reducer到底是什么,以及它为什么叫reducer?相关推荐
- 图解Redux中middleware的洋葱模型
原文发布于我的 GitHub 博客,欢迎 star ? 前言 最近翻出了之前分析的 applyMiddleware 发现自己又看不懂了?,重新看了一遍源代码,梳理了洋葱模型的实现方法,在这里分享一下. ...
- 一个插件让你在 Redux 中写 promise 事半功倍
Redux 的应用给我们开发带来了很多便利,让组件间交互不再那么复杂,但 Redux 也有它的短板,我们知道要通过 Redux 改变一个 state 需要定义 actionType→action→re ...
- Redux中的重要概念
Action/Reducer/Store 首先,先看看第一张图,图中展示了Redux的单向数据流,以及Action.Reducer和Store这三个核心概念. 下面就围绕上图,非别介绍Action.R ...
- [Redux/Mobx] 在redux中,什么是action?
[Redux/Mobx] 在redux中,什么是action? action是Redux中定义一个响应的动作,action总是有一个type属性,作为这个动作的唯一标识; Reducer函数则会根据这 ...
- [Redux/Mobx] 在Redux中怎么发起网络请求?
[Redux/Mobx] 在Redux中怎么发起网络请求? 如果单纯的使用Redux,因为redux的actionCreator返回一个plain object,所以不能在actionCreator中 ...
- [Redux/Mobx] Redux中异步action和同步action最大的区别是什么?
[Redux/Mobx] Redux中异步action和同步action最大的区别是什么? 同步action:执行了dispatch函数之后,对应的reducer纯函数立即得到执行,reducer执行 ...
- Fish Redux中的Dispatch是怎么实现的?
零.前言 我们在使用fish-redux构建应用的时候,界面代码(view)和事件的处理逻辑(reducer,effect)是完全解耦的,界面需要处理事件的时候将action分发给对应的事件处理逻辑去 ...
- Redux中的功能式React式编程简介
by Bhuvan Malik 通过布凡·马利克(Bhuvan Malik) Redux中的功能式React式编程简介 (An introduction to functional Reactive ...
- 理解redux中Middleware
如果你使用过 Express 或者 Koa 等服务端框架, 那么应该对 middleware 的概念不会陌生. 在这类框架中,middleware 是指可以被嵌入在框架接收请求到产生响应过程之中的代码 ...
- Redux中的Reducers
Redux中的action只是表明了在应用中发生了什么,但是并没有对数据state进行处理,Reducers就是用来处理数据的. 因为在Redux中只有一个state对象,所以在设计state时我们要 ...
最新文章
- 图片垂直居中的使用技巧
- 在Java 7里如何对文件进行操作
- JS发送跨域Post请求出现两次请求的解决办法
- 【软件安装】sublime安装方法
- Android-实现View滑动的6种方式
- ConcurrentHashMap的初步使用及场景
- PAT_B_1004_Java(20分)
- linux级别3怎么配置DNS,Linux下DNS服务器配置详解
- linux后台停止执行命令,Linux 命令的后台运行
- mybatis mysql 配置文件_mybatis简单应用(基于配置文件)_MySQL
- 【leetcode】排序题(python)
- Linux系统firewalld防火墙的应用实操(禁止屏蔽海外国外IP访问)
- 微软商店无法下载应用,VS2019无法下载插件问题解决方案
- vim常用操作记这些完全够用了
- 学会Python好找工作吗?这就告诉你答案
- Elasticsearch索引新增字段
- 【转】博弈论中的几个经典问题
- SQL注入绕过(passby)策略
- 基于Python的旅游景点的数据采集与分析的研究
- 松果在线报名系统网站源码
热门文章
- 服务器3389信息,服务器3389远程记录查看
- 论文解读:基于图神经网络与蛋白质接触图的药靶亲和力预测(一)2021SC@SDUSC
- [论文评析]Long-Tail Learning via Logit Adjustment,ICLR,2021
- windows图标文件夹_如何在Windows 10中获取Windows 7的旧文件夹图标
- 如何将产品发布到App Store上?
- 免费升级win10系统方法
- ssm启动不报错_ssm整合 启动表现层报错。。。
- 数据仓库之-历史数据存储方案
- 梦幻西游战斗中服务器维护,梦幻西游10月22日维护公告 连续战斗自动问题修复...
- axure不能导出图片_Axure7.0导出图片提示内存不足,如何解决?