首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redux(六):源码分析之bindActionCreators、compose

Redux(六):源码分析之bindActionCreators、compose

原创
作者头像
Ashen
修改2020-06-01 14:37:58
5670
修改2020-06-01 14:37:58
举报

一、bindActionCreators的作用

action是一个包含type属性的纯对象,派发一个action需要调用store的dispatch()方法。派发操作是非常频繁的,如果每个react组件都引入store再派发action会显的很冗余。如果有一个文件能统一管理这些派发操作,然后在react组件中引入这些方法执行,像这样:

const addTodo = function(action){
  store.dispatch(action);
};
export {addTodo}

在一个大型应用中,state树的分支会非常多,每一个分支区域所对应的action操作也可能有很多,且通常同一个分支区域的action.type会保持前缀相同,所以对于这种情况比较合理的方式是编写actionCreator()函数,比如:

function todosActionCreator(type,data){
  return{
    type:"TODO_"+type,
    data
  }
}
const addTodo = function(type,data){
  store.dispatch(todosActionCreator(type,data));
};
addTodo("ADD",{
  text:"do something"
});

每个分支区域可能有对应的actionCreator,Redux就提供了这样的工具函数,也就是bindActionCreators。

二、bindActionCreators.js源码分析

1、1行——5行

定义bindActionCreator()函数。

function bindActionCreator(actionCreator, dispatch) {
  return function() {
    return dispatch(actionCreator.apply(this, arguments))
  }
}

bindActionCreator()会返回一个action派发函数,派发函数的参数会作为自定义actionCreator()的参数。

2、28行——52行

定义bindActionCreators()函数。

export default function bindActionCreators(actionCreators, dispatch) {
  if (typeof actionCreators === 'function') {
    return bindActionCreator(actionCreators, dispatch)
  }

  if (typeof actionCreators !== 'object' || actionCreators === null) {
    throw new Error(
      `bindActionCreators expected an object or a function, instead received ${
        actionCreators === null ? 'null' : typeof actionCreators
      }. ` +
        `Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
    )
  }

  const keys = Object.keys(actionCreators)
  const boundActionCreators = {}
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i]
    const actionCreator = actionCreators[key]
    if (typeof actionCreator === 'function') {
      boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
    }
  }
  return boundActionCreators
}

bindActionCreators()函数允许actionCreators参数是一个对象,遍历该对象并依次调用bindActionCreator,最终返回一个对象,调用对应的属性并执行便可派发相应的action。

三、compose函数

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)))
}

compose可以接收多个参数(必须是函数),返回一个函数。返回函数的参数会作为最后一个参数函数的参数,参数函数会由后向前执行,每个函数的返回值会作为下一个函数的参数,最后执行函数的返回值会作为整体的返回值。看这个例子就懂了:

const result = compose(
  (a)=>{console.log("a",a);return a+1;},
  (b)=>{console.log("b",b);return b+1;},
  (c)=>{console.log("c",c);return c+1;}
);
console.log(result(1));
/*
* 打印结果:
* c 1
* b 2
* a 3
* 4
* */

这个函数接下来就会出现在下一章的中间件——applyMiddleware.js

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、bindActionCreators的作用
  • 二、bindActionCreators.js源码分析
    • 1、1行——5行
      • 2、28行——52行
      • 三、compose函数
      相关产品与服务
      消息队列 TDMQ
      消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档