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. Dynamics CRM 修改自定义实体名字及属性前缀(架构名称)

    本文章以2013为例(2011同理,4.0比较简单直接在系统设置的自定义中设置即可). 1.设置-->自定义项-->发布者,下图中的红框内的即为需要设置的前缀. 2.设置-->解决方 ...

  2. Java进阶(二十二)使用FileOutputStream写入文件

    Java使用FileOutputStream写入文件 绪 在Java中,文件输出流是一种用于处理原始二进制数据的字节流类.为了将数据写入到文件中,必须将数据转换为字节,并保存到文件.请参阅下面的完整的 ...

  3. C/C++ Volatile关键词深度剖析(转)

    本文转载自博文C/C++ Volatile关键词深度剖析. 背景 前几天,发了一条如下的微博 (关于C/C++ Volatile关键词的使用建议): 此微博,引发了朋友们的大量讨论:赞同者有之:批评者 ...

  4. HDFS读写数据过程

    一.文件的打开 1.1.客户端 HDFS打开一个文件,需要在客户端调用DistributedFileSystem.open(Path f, int bufferSize),其实现为: public F ...

  5. 解决ADT大量出现"Unexpected value from nativeGetEnabledTags: 0"的问题

    在过滤器中输入下面的代码即可:(此方法搜索于网略) ^(?!.*(nativeGetEnabledTags)).*$ 

  6. Android主题切换—夜间/白天模式探究

    现在市面上众多阅读类App都提供了两种主题:白天or夜间. 上述两幅图片,正是两款App的夜间模式效果,所以,依据这个功能,来看看切换主题到底是怎么实现的(当然现在github有好多PluginThe ...

  7. ibatis中多表联接查询

     目前,我在做项目的时候,用到了spring + struts2 +ibatis 框架.平时用到的都是一张简单的表,来进行数据的增.删.改.查.而现在突然需要用到其它的一张表,或多张表进行联接查询 ...

  8. HI258摄像头旋转配置问题

    {0x28, 0x04}, //Full row start y-flip  {0x29, 0x01}, //Pre1 row start no-flip {0x2a, 0x02}, //Pre1 r ...

  9. android的ndk开发简介-android学习之旅(93)

    环境搭建 1.安装ndk 2.安装cygwin (android是基于linux的Framework,运行的本地库是.SO,而不是.dll库,大部分都实在windows下开发,如果是linux就没这个 ...

  10. lambda表达式初步

    // Lambda_test20140801.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <algorithm& ...