当前位置: 首页 > news >正文

从 源码 谈谈 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在处理中间的中的强大作用。

 

相关文章:

  • 【译】理解JavaScript:new 关键字
  • 开发者论坛一周精粹(第四十三期) 物联网全栈教程 ECSphp版本降级
  • Waymo宣布今年在凤凰城推出自动驾驶汽车打车服务,此前已获得商业执照
  • 数学随记—公式定理
  • docker操作使用
  • 【枚举】【贪心】Codeforces Round #482 (Div. 2) B. Treasure Hunt
  • Python学习笔记__6.3章 继承和多态
  • 如何高效的编写与同步博客 (.NET Core 小工具实现)
  • Mongodb对集合(表)和数据的CRUD操作
  • (2)Java 简介
  • innobackupex 在增量的基础上增量备份
  • elasticsearch+logstash+kibana+redis
  • 有向无环图(DAG)的最小路径覆盖
  • winSCP:无权访问
  • VS Code 折腾记 - (13) VS Live Share (可提高效率的代码实时协作插件)的使用姿势
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • java概述
  • KMP算法及优化
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • PHP的Ev教程三(Periodic watcher)
  • Sass Day-01
  • zookeeper系列(七)实战分布式命名服务
  • 诡异!React stopPropagation失灵
  • 区块链分支循环
  • 网页视频流m3u8/ts视频下载
  • 我有几个粽子,和一个故事
  • 无服务器化是企业 IT 架构的未来吗?
  • const的用法,特别是用在函数前面与后面的区别
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • # include “ “ 和 # include < >两者的区别
  • #13 yum、编译安装与sed命令的使用
  • $L^p$ 调和函数恒为零
  • (12)Linux 常见的三种进程状态
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (python)数据结构---字典
  • (windows2012共享文件夹和防火墙设置
  • (二)windows配置JDK环境
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (四)库存超卖案例实战——优化redis分布式锁
  • (算法二)滑动窗口
  • (转载)利用webkit抓取动态网页和链接
  • **python多态
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .cfg\.dat\.mak(持续补充)
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net FrameWork简介,数组,枚举
  • .net refrector
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • /bin/bash^M: bad interpreter: No such file or directory