资讯专栏INFORMATION COLUMN

redux之compose

huayeluoliuhen / 2181人阅读

摘要:是状态管理库,与其他框架如是没有直接关系,所以可以脱离在别的环境下使用。所以一共就五个文件需要看,这五个文件也就是暴露出去的五个。所以经过处理过之后,函数就变成我们想要的格式了。总结函数在函数式编程里很常见。

redux 是状态管理库,与其他框架如 react 是没有直接关系,所以 redux 可以脱离 react 在别的环境下使用。由于没有和react 相关逻辑耦合,所以 redux 的源码很纯粹,目的就是把如何数据管理好。而真正在 react 项目中使用 redux 时,是需要有一个 react-redux 当作连接器,去连接 reactredux

没看 redux 源码之前,我觉得看 redux 应该是件很困难的事情,因为当初在学 redux 如何使用的时候就已经被 redux 繁多的概念所淹没。真正翻看 redux 源码的时候,会发现 redux 源码内容相当之少,代码量也相当少,代码质量也相当高,所以是非常值得看的源码。

目录结构

其他目录都可以不看,直接看 ./src 吧:

.REDUXSRC
│ applyMiddleware.js
│ bindActionCreators.js
│ combineReducers.js
│ compose.js
│ createStore.js
│ index.js

└─utils

    actionTypes.js
    isPlainObject.js
    warning.js

index.js 就是把 applyMiddleware.js 等汇集再统一暴露出去。utils 里面就放一些辅助函数。所以一共就五个文件需要看,这五个文件也就是 redux 暴露出去的五个 API

// index.js
import createStore from "./createStore"
import combineReducers from "./combineReducers"
import bindActionCreators from "./bindActionCreators"
import applyMiddleware from "./applyMiddleware"
import compose from "./compose"
import warning from "./utils/warning"
import __DO_NOT_USE__ActionTypes from "./utils/actionTypes"

// 忽略内容

export {
  createStore,
  combineReducers,
  bindActionCreators,
  applyMiddleware,
  compose,
  __DO_NOT_USE__ActionTypes
}
compose.js

这是五个 API 里唯一一个能多带带拿出来用的函数,就是函数式编程里常用的组合函数,和 redux 本身没有什么多大关系,先了解下函数式编程的一些概念:

纯函数是这样一种函数,即相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用。
代码组合

代码:

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

其实 compose 函数做的事就是把 var a = fn1(fn2(fn3(fn4(x)))) 这种嵌套的调用方式改成 var a = compose(fn1,fn2,fn3,fn4)(x) 的方式调用。

reduxcompose 实现很简洁,用了数组的 reduce 方法,reduce 的用法可以参照 mdn。

核心代码就一句:return funcs.reduce((a,b) => (..args) => a(b(...args)))

我虽然经常写 reduce 函数,但是看到这句代码还是有点懵的,所以这里举一个实际的例子,看看这个函数是怎么执行的:

import {compose} from "redux"
let x = 10
function fn1 (x) {return x + 1}
function fn2(x) {return x + 2}
function fn3(x) {return x + 3}
function fn4(x) {return x + 4}

// 假设我这里想求得这样的值
let a = fn1(fn2(fn3(fn4(x)))) // 10 + 4 + 3 + 2 + 1 = 20

// 根据compose的功能,我们可以把上面的这条式子改成如下:
let composeFn = compose(fn1, fn2, fn3, fn4)
let b = composeFn(x) // 理论上也应该得到20

看一下 compose(fn1, fn2, fn3, fn4)根据 compose 的源码, 其实执行的就是:
[fn1,fn2,fn3.fn4].reduce((a, b) => (...args) => a(b(...args)))

第几轮循环 a的值 b的值 返回的值
第一轮循环 fn1 fn2 (...args) => fn1(fn2(...args))
第二轮循环 (...args) => fn1(fn2(...args)) fn3 (...args) => fn1(fn2(fn3(...args)))
第三轮循环 (...args) => fn1(fn2(fn3(...args))) fn4 (...args) => fn1(fn2(fn3(fn4(...args))))

循环最后的返回值就是 (...args) => fn1(fn2(fn3(fn4(...args))))。所以经过 compose 处理过之后,函数就变成我们想要的格式了。

总结

compose 函数在函数式编程里很常见。这里 redux 的对 compose 实现很简单,理解起来却没有那么容易,主要还是因为对 Array.prototype.reduce 函数没有那么熟练,其次就是这种接受函数返回函数的写法,再配上几个连续的 => ,容易看晕。

这是 redux 解读的第一篇,后续把几个 API 都讲一下。特别是 applyMiddleware 这个 API 有用到这个 compose 来组合中间件,也是有那么一个点比较难理解。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96375.html

相关文章

  • Redux 莞式教程 进阶篇

    摘要:进阶教程原文保持更新写在前面相信您已经看过简明教程,本教程是简明教程的实战化版本,伴随源码分析用的是编写,看到有疑惑的地方的,可以复制粘贴到这里在线编译总览在的源码目录,我们可以看到如下文件结构打酱油的,负责在控制台显示警告信息入口文件除去 Redux 进阶教程 原文(保持更新):https://github.com/kenberkele... 写在前面 相信您已经看过 Redux ...

    岳光 评论0 收藏0
  • React系列 Redux 架构模式

    摘要:原文地址没想到这篇文章这么晚才出,最近发生了太多的事情,已致于心态全无,最终也离开了现在的公司,没想到是这么的狼狈一个人的光芒可以放到很大也可以小到微乎其微,如果不能好好的规划最终也只能默默的承受世上没有相同的感同身受,感受真实才能真正的 原文地址:https://gmiam.com/post/react-... 没想到这篇文章这么晚才出,最近发生了太多的事情,已致于心态全无,最终也离...

    xfee 评论0 收藏0
  • Redux story-1:who creates it?

    摘要:而不是卷入无休止的撕逼,用了某某而产生的优越,甚至借贬低他人来抬高自己。 前言  这是一个系列文章,旨在分享在react及相关技术栈实践过程中的个人感悟,心得。如果有不好的地方,欢迎各位批评指正。  由于对react本身还未深入了解,今天我们先来谈一谈redux相关的问题。 Who creates it?  Dan Abramov是redux的作者,同时,他也是Create React...

    lavor 评论0 收藏0
  • 简单介绍redux的中间件

    摘要:改地方就是将塞进所有的中间件中,然后返回一个函数,而中间件的形式后面会说到。流程图异步信息说道这里应该会对中间件有个大致的认识,接下来介绍一下常用的中间件以及自己写一个中间件。 用过react的同学都知道在redux的存在,redux就是一种前端用来存储数据的仓库,并对改仓库进行增删改查操作的一种框架,它不仅仅适用于react,也使用于其他前端框架。研究过redux源码的人都觉得该源码...

    philadelphia 评论0 收藏0
  • 浅析Redux源码

    摘要:用法源码由在年创建的科技术语。我们除去源码校验函数部分,从最终返回的大的来看。这个返回值无法被识别。洋葱模型我们来看源码源码每个都以作为参数进行注入,返回一个新的链。改变原始组数,是一种副作用。 @(Redux)[|用法|源码] Redux 由Dan Abramov在2015年创建的科技术语。是受2014年Facebook的Flux架构以及函数式编程语言Elm启发。很快,Redux因其...

    lifesimple 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<