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

一般 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);

bindActionCreators & combineReducers 使用记录_第1张图片

使用 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);
bindActionCreators & combineReducers 使用记录_第2张图片

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

export default connect(
  (state) => state,
  (dispatch) => {
  	// 返回的内容直接绑定到 props 
    return {
    //无线套娃
      action1: {
        action2: bindActionCreators(actions, dispatch),
      },
    };
  }
)(App);
bindActionCreators & combineReducers 使用记录_第3张图片

**但是 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 不能绑定成功

bindActionCreators & combineReducers 使用记录_第4张图片

自定义方法递归处理 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 
; }; export default connect( (state) => state, (dispatch) => { return { action: bindActionCreatorsPlus(actions, dispatch), }; }, )(Application);
bindActionCreators & combineReducers 使用记录_第5张图片

绑定成功,如此不管嵌套几层,都可以把 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 };

相关文章推荐

  • redux-actions详解教程记录

你可能感兴趣的:(#,React,进阶之路,前端知识图谱,react,redux,大前端)