compose,英文意思 组成,构成。

  它的作用也是通过一系列的骚操作,实现任意的、多种的、不同的功能模块的组合,用来加强组件。


看看源码

  https://github.com/reactjs/redux/blob/v3.7.2/src/compose.js

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)))
}

  是不是感觉很简单,关键就这一句嘛,结果也就是一层套一层的函数调用

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

如果
  const funcs = [a, b, c, d];
那么
  compose(...funcs)(...args) = a(b(c(d(...args))));

  其实就是func中的方法,倒着一个一个调用,前一个调用返回的结果作为后一个的参数,第一个方法的参数是...args;

  来来来,看看个例子:

  git代码:https://github.com/wayaha/react-demos-compose(如果对您有帮助,请您帮我点颗star)

import React, { Component } from 'react';
import { compose, bindActionCreators } from 'redux';
import {connect} from 'react-redux'
import { AddStaff, ChangeStaffData, DeleteStaff, ShowStaffMsg } from '../HOC';
import AddPanel from './AddPanel';
// import { list } from 'postcss';
import { addAction, deleteAction, changeAction, showAction } from '../../redux/company';
import './index.scss'; const Enhancer = compose(AddStaff, ChangeStaffData, DeleteStaff, ShowStaffMsg); class Manage extends Component { /*
   *some code
   */
export default connect(state => ({
staffData: state.company.staffData,
name: state.company.name
}), dispatch => ({
dispatch,
actions: bindActionCreators({
addAction,
deleteAction,
changeAction,
showAction
}, dispatch)
}))(Enhancer(Manage));

  上边蓝色的部分可以看作是,compose(AddStaff, ChangeStaffData, DeleteStaff, ShowStaffMsg) (Manage)

  

  compose 组合了四个模块,模块相似,代码结构如下,高阶组件的反向继承:

const AddStaff = WrapperComponent => {
return class Enhancer extends WrapperComponent { addStaff = () => {
const { name, staffId, department, work } = this.state;
const { actions: { addAction } } = this.props;
addAction({ name, staffId, department, work })
this.handleCancel();
}; render () {
return super.render();
};
};
}; export default AddStaff;

 高阶组件可以看作是,一个方法,返回的包装后的组件,它也只是为传入组件的props添加一个方法,然后返回。

WrapperComponent => {
  addStaff = () => {
// do something
};
  return <WrapperComponent {...this.props, addStaff: addStaff}/> 
};

  同样,

  compose(AddStaff, ChangeStaffData, DeleteStaff, ShowStaffMsg) (Manage) 的结果就可以是:

     compose( AddStaff (  ChangeStaddData (  DeleteStaff ( ShowStaddMsg ( Manage ) ) )  ) )

  ShowStaddMsg ( Manage ) 返回一个拥有ShowStaddMsg的Manage组件;

  DeleteStaff ( ShowStaddMsg ( Manage ) )返回一个拥有DeleteStaff 、ShowStaddMsg的Manage组件;

  ChangeStaddData ( DeleteStaff ( ShowStaddMsg ( Manage ) ) ) 返回一个拥有ChangeStaddData 、DeleteStaff 、ShowStaddMsg的Manage组件;

  最终返回一个拥有添加、修改、删除、展示四大功能的加强组件;

用途:

  这样的操作很容易实现功能的组合拼装、代码复用;可以根据需要组合不同的功能;看过中间件源码的大牛,应该都看到compose在处理中间的中的强大作用。

从 源码 谈谈 redux compose的更多相关文章

  1. Redux源码分析之compose

    Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...

  2. redux源码阅读之compose,applyMiddleware

    我的观点是,看别人的源码,不追求一定要能原样造轮子,单纯就是学习知识,对于程序员的提高就足够了.在阅读redux的compose源码之前,我们先学一些前置的知识. redux源码阅读之compose, ...

  3. redux源码解析-redux的架构

    redux很小的一个框架,是从flux演变过来的,尽管只有775行,但是它的功能很重要.react要应用于生成环境必须要用flux或者redux,redux是flux的进化产物,优于flux. 而且r ...

  4. React深入源码--了解Redux用法之Provider

    在Redux中最核心的自然是组件,以及组件相关的事件与数据流方式.但是我们在Redux中并没有采用传统的方式在getInitialState()中去初始化数据,而是采用Provider统一处理,省去了 ...

  5. 结合源码谈谈ThreadLocal!

    目录 ThreadLocal的作用 ThreadLocal 1.对象初始化 2.获取变量 3.设置变量 4.移除变量 ThreadLocalMap 1.Entry 2.初始化 3.获取Entry 4. ...

  6. Redux源码分析之createStore

    接着前面的,我们继续,打开createStore.js, 直接看最后, createStore返回的就是一个带着5个方法的对象. return { dispatch, subscribe, getSt ...

  7. Redux源码分析之applyMiddleware

    Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...

  8. Redux源码分析之基本概念

    Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...

  9. Redux源码分析之bindActionCreators

    Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...

随机推荐

  1. javascript语法之字符串转换成数字

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 完美滑动顶部固定ScrollView,合并可以上拉,下拉加载更多

    先看效果: 主要处理: 使用PullToRefreshScrollView修改内部的scrollView源码,更换成可以固定顶部的自定义scrollView @Override protected S ...

  3. JSP 对象的作用范围

    在JSP中,对象有四种范围:page.request.session和application page范围             所谓的page范围指单一的JSP页面范围,page范围内的对象只能在 ...

  4. Linux 内核配置机制(make menuconfig、Kconfig、makefile)讲解

    前面我们介绍模块编程的时候介绍了驱动进入内核有两种方式:模块和直接编译进内核,并介绍了模块的一种编译方式--在一个独立的文件夹通过makefile配合内核源码路径完成 那么如何将驱动直接编译进内核呢? ...

  5. TCP的核心系列 — ACK的处理(二)

    本文主要内容:tcp_ack()中的一些细节,如发送窗口的更新.持续定时器等. 内核版本:3.2.12 Author:zhangskd @ csdn 发送窗口的更新 什么时候需要更新发送窗口呢? (1 ...

  6. 介绍一种很棒的wince 如何替换系统声音的方法

    Topic:介绍一种很棒的wince 如何替换系统声音的方法(作者:Baiduluckyboy) //------------------------------------------------- ...

  7. obj-c编程06:反射与元编程初步

    我们知道对于现如今的动态语言比如ruby而言,反射和元编程以及支持的非常灵活了,你完全可以跳过常规的手段,而利用反射来查询或调用对象的私有方法.而obj-c对反射的支持略显小繁琐,而且在开了ARC后同 ...

  8. 恶补web之四:xhtml学习

    xhtml是更严格更纯净的html代码,它与html4.01兼容.xhtml是以xml重构额html4.01 xhtml与2000年1月26日成为w3c标准,w3c将xhtml定义为最新的html版本 ...

  9. 使用XStream是实现XML与Java对象的转换(3)--注解

    六.使用注解(Annotation) 总是使用XStream对象的别名方法和注册转换器,会让人感到非常的乏味,又会产生很多重复性代码,于是我们可以使用注解的方式来配置要序列化的POJO对象. 1,最基 ...

  10. Unknown entity: org.jbpm.services.task.audit.TaskEventImpl

    1. use this persistence.xml - simply copy it into src/main/resources/META-INF please note the name o ...