bindActionCreators & combineReducers 使用记录

阅读 redux 源码的时候,发现 redux 给我们提供了一系列方法。

  • createStore ( redux 创建 store; 必备 )
  • applyMiddleware ( redux 注入中间件 )
  • compose ( redux 组合多个中间件)

下面这两个方法是干啥用的呢?

  • bindActionCreators
  • combineReducers

一、bindActionCreators

1. 定义 action 文件

一个文件定义多个 action 方法,一般跟某一个业务相关的 action 放在同一个文件中。

//action.js

export const Action1 = () => {
  return { type: "action", payload: "Action1" };
};

export const Action2 = () => {
  return (dispatch) => {
    dispatch({ type: "action", payload: "Action2" });
  };
};

export const Action3 = () => {
  return { type: "action", payload: "Action3" };
};

...

2. 一般的action绑定方式

// App.jsx

import * as actions from "./action";

export default connect(
  (state) => state,
  (dispatch) => {
  	//返回一个 action 集合对象
    return {
      Action1: () => dispatch(actions.Action1()),
      Action2: () => dispatch(actions.Action2()),
      Action3: () => dispatch(actions.Action3()),
        ...
    };
  }
)(App);
image-20201202172224494

一般 action 比较少的时候用这种方式绑定还能接受。如果对于复杂的项目,一个业务需要绑定的 action 超过10个甚至更多,还用这种罗列式绑定不仅代码重复而且繁重。

图片可以看出 react-redux 将 action 成功的绑定到了 props 属性上。

3. bindActionCreators 使用

// App.jsx

import { bindActionCreators } from "redux";
import * as actions from "./action";

export default connect(
  (state) => state,
  (dispatch) => {
    return {
      ...bindActionCreators(actions, dispatch),
    };
  }
)(App);

image-20201202172828759

使用 bindActionCreators 绑定 action 一行代码就搞定。

有的人不喜欢把 action 方法直接放在 props 第一层,那么我再套一层就好了

// App.jsx

import { bindActionCreators } from "redux";
import * as actions from "./action";

...

export default connect(
  (state) => state,
  (dispatch) => {
    return {
      actions: bindActionCreators(actions, dispatch),
    };
  }
)(App);
示意图

connect 方法会把方法返回的对象绑定到 props 上,那么只要我搞定,我可以无线套娃。

export default connect(
  (state) => state,
  (dispatch) => {
  	// 返回的内容直接绑定到 props 
    return {
    //无线套娃
      action1: {
        action2: bindActionCreators(actions, dispatch),
      },
    };
  }
)(App);
示意图

**但是 bindActionCreators 只能处理一层actions对象(通过源码分析),但是很多时候我们需要把多个 action 方法集中到同一个 actions.js 文件,这个时候用 bindActionCreators 处理绑定 action,就只会处理第一层 **

举例说明🌰

  • commonAction.js
export const commonAction1 = () => {
  return { type: 'xxx' };
};

export const commonAction2 = () => {
  return { type: 'xxx' };
};
  • actions.js
import { commonAction1, commonAction2 } from './commonAction';
export const actions = {
	//引入公共模块 action
  commonAction1,
  commonAction2,
  Action1: () => {
    return { type: 'xxx' };
  },
  Action2: () => {
    return { type: 'xxx' };
  },
  Action3: () => {
    return { type: 'xxx' };
  },
};

直接用 bindActionCreators 方法处理 action 不能绑定成功

image-20201204220142912

🏁🏁🏁🏁 自定义方法递归处理 action

  • 新建 bindActionCreatorsPlus.js
// bindActionCreatorsPlus.js
import { bindActionCreators } from 'redux';

export default function bindActionCreatorsPlus(actions, dispatch) {
  if (typeof actions !== 'object' || !actions) {
    throw new Error('invalid actions');
  }

  let result = {};
  for (let key in actions) {
    if (actions.hasOwnProperty(key)) {
      const creator = actions[key];
      if (typeof creator === 'object' && creator) {
        //递归执行
        result[key] = bindActionCreatorsPlus(creator, dispatch);
      } else if (typeof creator === 'function') {
        result[key] = bindActionCreators(creator, dispatch);
      }
    }
  }
  return result;
}
  • 调用自定义 bindActionCreatorsPlus 方法
import React from 'react';
//引入 bindActionCreatorsPlus.js
import bindActionCreatorsPlus from './bindActionCreatorsPlus';
import { connect } from 'react-redux';
import * as actions from './action';

const Application = (props) => {
  console.log(props);
  return <div></div>;
};

export default connect(
  (state) => state,
  (dispatch) => {
    return {
      action: bindActionCreatorsPlus(actions, dispatch),
    };
  },
)(Application);
image-20201204220523018

📢 绑定成功,如此不管嵌套几层,都可以把 action 方法绑定到 props


二、combineReducers

createStore 方法创建新 store 需要传入一个 reducer 方法 。但是复杂的业务需要把 reducer 区分开,但是 createStore 只能接受一个 reducer。 需要把多个 reducer 合并成同一个,combineReducers 方法就是为了合并 reducer。

import { createStore, combineReducers } from "redux";

// 此处偷懒,把多个 reducer放在一起了
//第一个 reducer
const oneReducer = (state = {}, action) => {
  switch (action.type) {
    case "action":
      return { ...state, actions: action.payload };
    case "levenx":
      return { ...state, AB: action.payload };
    default:
      return state;
  }
};

// 第二个 reducer
const twoReducer = (state = {}, action) => {
  switch (action.type) {
    case "action":
      return { ...state, actions: action.payload };
    case "levenx":
      return { ...state, AB: action.payload };
    default:
      return state;
  }
};

.... // N 个reducer

const reducer = combineReducers({
	one: oneReducer,
	two: twoReducer });

// 创建 store 实例
const store = createStore(reducer, {});

export { store };

相关文章推荐

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐闻x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值