天天看點

從 源碼 談談 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在進行中間的中的強大作用。

繼續閱讀