从 源码 谈谈 redux compose
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的更多相关文章
- Redux源码分析之compose
Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...
- redux源码阅读之compose,applyMiddleware
我的观点是,看别人的源码,不追求一定要能原样造轮子,单纯就是学习知识,对于程序员的提高就足够了.在阅读redux的compose源码之前,我们先学一些前置的知识. redux源码阅读之compose, ...
- redux源码解析-redux的架构
redux很小的一个框架,是从flux演变过来的,尽管只有775行,但是它的功能很重要.react要应用于生成环境必须要用flux或者redux,redux是flux的进化产物,优于flux. 而且r ...
- React深入源码--了解Redux用法之Provider
在Redux中最核心的自然是组件,以及组件相关的事件与数据流方式.但是我们在Redux中并没有采用传统的方式在getInitialState()中去初始化数据,而是采用Provider统一处理,省去了 ...
- 结合源码谈谈ThreadLocal!
目录 ThreadLocal的作用 ThreadLocal 1.对象初始化 2.获取变量 3.设置变量 4.移除变量 ThreadLocalMap 1.Entry 2.初始化 3.获取Entry 4. ...
- Redux源码分析之createStore
接着前面的,我们继续,打开createStore.js, 直接看最后, createStore返回的就是一个带着5个方法的对象. return { dispatch, subscribe, getSt ...
- Redux源码分析之applyMiddleware
Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...
- Redux源码分析之基本概念
Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...
- Redux源码分析之bindActionCreators
Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...
随机推荐
- Dynamics CRM 修改自定义实体名字及属性前缀(架构名称)
本文章以2013为例(2011同理,4.0比较简单直接在系统设置的自定义中设置即可). 1.设置-->自定义项-->发布者,下图中的红框内的即为需要设置的前缀. 2.设置-->解决方 ...
- Java进阶(二十二)使用FileOutputStream写入文件
Java使用FileOutputStream写入文件 绪 在Java中,文件输出流是一种用于处理原始二进制数据的字节流类.为了将数据写入到文件中,必须将数据转换为字节,并保存到文件.请参阅下面的完整的 ...
- C/C++ Volatile关键词深度剖析(转)
本文转载自博文C/C++ Volatile关键词深度剖析. 背景 前几天,发了一条如下的微博 (关于C/C++ Volatile关键词的使用建议): 此微博,引发了朋友们的大量讨论:赞同者有之:批评者 ...
- HDFS读写数据过程
一.文件的打开 1.1.客户端 HDFS打开一个文件,需要在客户端调用DistributedFileSystem.open(Path f, int bufferSize),其实现为: public F ...
- 解决ADT大量出现"Unexpected value from nativeGetEnabledTags: 0"的问题
在过滤器中输入下面的代码即可:(此方法搜索于网略) ^(?!.*(nativeGetEnabledTags)).*$
- Android主题切换—夜间/白天模式探究
现在市面上众多阅读类App都提供了两种主题:白天or夜间. 上述两幅图片,正是两款App的夜间模式效果,所以,依据这个功能,来看看切换主题到底是怎么实现的(当然现在github有好多PluginThe ...
- ibatis中多表联接查询
目前,我在做项目的时候,用到了spring + struts2 +ibatis 框架.平时用到的都是一张简单的表,来进行数据的增.删.改.查.而现在突然需要用到其它的一张表,或多张表进行联接查询 ...
- HI258摄像头旋转配置问题
{0x28, 0x04}, //Full row start y-flip {0x29, 0x01}, //Pre1 row start no-flip {0x2a, 0x02}, //Pre1 r ...
- android的ndk开发简介-android学习之旅(93)
环境搭建 1.安装ndk 2.安装cygwin (android是基于linux的Framework,运行的本地库是.SO,而不是.dll库,大部分都实在windows下开发,如果是linux就没这个 ...
- lambda表达式初步
// Lambda_test20140801.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <algorithm& ...