Redux API

Redux API

2017, Sep 12    

redux的作用是什么呢

Redux专门用于管理状态。

Redux的主要优势之一是它可以帮你处理应用的共享状态。如果两个组件需要访问同一状态,该怎么办?这种两个组件同时需要访问同一状态的现象称为“共享状态”。

redux有哪些API?

  • createStore(reducer,[preloadState],enhancer/middleware)
  • combineReducers(reducers)
  • compose(…functions)
  • applyMiddleware(middlewares)
  • bindActionCreators(actionCreators,dispatch)

1)createStore(reducer,[preloadState],enhancer/middleware)

  • 创建 Redux store 来存放状态。
  • enhancer 为function。用来增强store。
  • Redux 定义有applyMiddleware来增强store,后面会单独讲applyMiddleware。
  • API {subscribe,dispatch,getState}

image

2)combineReducers(reducers)

把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数。

const reducers = getReducers({
  common,
  // 首页
  home,
  // 小程序
  applets,
  // 信息资讯
  info,
  // 公司介绍
  introduction,
});

const store = createStore(
  combineReducers(reducers),
  composeEnhancers(applyMiddleware(thunk)),
);

3)compose(…functions)

compose函数的作用就是组合函数的,将函数串联起来执行,将多个函数组合起来, 一个函数的输出结果是另一个函数的输入参数,一旦第一个函数开始执行,就会像多米诺骨牌一样推导执行了。

下面是一个非常简单用js 实现 compose的方法~

  var greeting = (firstName, lastName) => '  hello, ' + firstName + ' ' + lastName
  var toUpper = str => str.toUpperCase()
  var trim = str => str.trim()

  var compose = function(...args) { //args [f,f,f]
    var len = args.length
    var count = len - 1
    var result
    return function f1(...args1) { //'jack','smith'
      result = args[count].apply(this, args1)
      if (count <= 0) {
        return result
      } else {
        count--
        return f1.call(null, result)
      }
    }
  }
  var fn = compose(trim, toUpper, greeting)('jack','smith')
  trim(toUpper(greeting('jack','smith'))) ; //等同于这样

由此可见~ compose函数的作用就是组合函数的,将函数串联起来执行,将多个函数组合起来, 一个函数的输出结果是另一个函数的输入参数,一旦第一个函数开始执行,就会像多米诺骨牌一样推导执行了。

redux中compose的源码比较复杂,结合了数组的reduce方法~

   /**
   * Composes single-argument functions from right to left. The rightmost
   * function can take multiple arguments as it provides the signature for
   * the resulting composite function.
   *
   * @param {...Function} funcs The functions to compose.
   * @returns {Function} A function obtained by composing the argument functions
   * from right to left. For example, compose(f, g, h) is identical to doing
   * (...args) => f(g(h(...args))).
   */
  export default 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)));
  };

4)applyMiddleware(middlewares)

createStore源码~

image

redux 中applyMiddleware 的源码~

export default function applyMiddleware(...middlewares) {
  return (next)  => (reducer, initialState) => {
    var store = next(reducer, initialState);
    var dispatch = store.dispatch;
    var chain = [];
    var middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    };

    chain = middlewares.map(middleware =>
    middleware(middlewareAPI));
    dispatch = compose(...chain, store.dispatch);
    return {
      ...store,
      dispatch
    };
 };
};
  • 在applyMiddleware源码中,第一个next是createStore中传来的createStore,说明如果传了enhancer,创建store是在applyMiddleware中完成。
  • middlewareAPI 是一个精简的store.
  • middleware 的范式是:(store) => (next) => (action) => {}。
  • 经过遍历,chain 中间件数组中包含的每个中间件的形式都变成了 (next) => (action) => {} 的形式。
  • 调用 compose 函数,如 chian = [middleware1, middleware2, middleware3], 则 dispatch = compose(…chain)(store.dispatch) 即执行 middleware1(middleware2(middleware3(store.dispatch)));
  • 返回的还是store(包含的dispatch功能增强了)

5)bindActionCreators(actionCreators,dispatch)

//action.js

function action1(){
  return {
   type:'type1'
  }
}
function action2(){
  return {
   type:'type2'
  }
}

import * as oldActionCreator from './action.js'

let newAction = bindActionCreators(oldActionCreator,dispatch);

我们将组合oldAction和dispatch的对象传递给子组件,在子组件中,调用newAction.action1, 相当于实现了dispatch(action1)。于是我们就实现了在没有store和dispatch组件中, 如何调用dispatch(action)。

如果不嫌麻烦使用import {} from ‘react-redux’ 的方式,这个接口就没有什么卵用了~。