從 原始碼 談談 redux compose

heart_of_time發表於2018-05-14

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在處理中間的中的強大作用。

 

相關文章