从 源码 谈谈 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)))<br /><br />如果
  const funcs = [a, b, c, d];<br />那么
<span>  compose(...funcs)(...args) = a(b(c(d(...args))));

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

来来来,看看个例子:

git代码:https://github.com/wayaha/react-demos-compose

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 =<strong> compose</strong>(AddStaff, ChangeStaffData, DeleteStaff, ShowStaffMsg);

class Manage extends Component {
 
    /*<br />   *some code<br />   */<br />
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 => {<br />
<span>  addStaff = () =><span> {
       // do something<span><span><span>
   };
  return <WrapperComponent {...this.props, addStaff: addStaff}/>
<em>};</em>

同样,

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

相关推荐