Action

  1. action是一个plain-object(平面对象)
    1. 它的proto指向Object.prototype
  2. 通常,使用payload属性表示附加数据(没有强制要求)
  3. action中必须有type属性,该属性用于描述操作的类型
    1. 但是,没有对type的类型做出要求
  4. 在大型项目,由于操作类型非常多,为了避免硬编码(hard code),会将action的类型存放到一个或一些单独的文件中(样板代码)。

    1. export const INCREASE = Symbol("INCREASE");
    2. export const DECREASE = Symbol("DECREASE");
    3. export const SETNUMBER = Symbol('SETNUMBER');
  5. 为了方面传递action,通常会使用action创建函数(action creator)来创建action ```json

import * as ActionTypes from ‘./action-type’

export function getIncreaseAction() { return { type: ActionTypes.INCREASE } }

export function getDecreaseAction() { return { type: ActionTypes.DECREASE } }

export function getSetNumberAction(data) { return { type: ActionTypes.SETNUMBER, payload: data } }

  1. 1. action创建函数应为无副作用的纯函数
  2. 1. 不能以任何形式改动参数
  3. 1. 不可以有异步
  4. 1. 不可以对外部环境中的数据造成影响
  5. 6. 为了方便利用action创建函数来分发(触发)actionredux提供了一个函数`bindActionCreators`,该函数用于增强action创建函数的功能,使它不仅可以创建action,并且创建后会自动完成分发。
  6. ```json
  7. import { createStore, bindActionCreators } from 'redux'
  8. import * as ActionCreator from './action/numer-actions'
  9. const bindActions = bindActionCreators(ActionCreator, store.dispatch)
  10. // 向仓库分发action
  11. // store.dispatch(ActionCreator.getSetNumberAction(4));
  12. bindActions.getSetNumberAction(3);

这里bindActionCreators根据ActionCreator(就是上面的number-actions.js代码块)和store.dispatch的创建函数,生成一个具有相同属性且属性值完全相似的对象,伺候在使用的时候,不必使用store.dispatch(ActionCreator.getSetNumberAction(4));的调用方式,可以直接使用bindActions.getSetNumberAction(3);

这里我们猜测一下bindActionCreators函数的原理

  1. 根据ActionCreator对象,生成一个新的跟ActionCreator对象属性一样的新对象
  2. 临时保存ActionCreator的每一个属性的值(这里是一个函数),
  3. 新对象属性值(也是一个函数)里面,首先调用ActionCreator的每一个属性,得到action,然后调用store.disatch,把action传入
  4. 返回新的对象

    完整的demo

  1. import { createStore, bindActionCreators } from 'redux'
  2. import * as ActionTypes from './action/action-type'
  3. import * as ActionCreator from './action/numer-actions'
  4. // 假设仓库中仅存放了一个数字,该数字的变化可能是+1或-1
  5. // 约定action的格式 {type:'操作类型',payload:附加数据}
  6. /**
  7. * reducer本质上事宜个普通的函数
  8. * @param {*} state 之前仓库中的状态(数据)
  9. * @param {*} action 描述要操作什么对象
  10. * @return 返回一个新的数据
  11. */
  12. function reducer(state, action) {
  13. switch (action.type) {
  14. case ActionTypes.INCREASE:
  15. return state + 1;
  16. case ActionTypes.DECREASE:
  17. return state - 1;
  18. case ActionTypes.SETNUMBER:
  19. return action.payload;
  20. default:
  21. return state;// 如果是一个无效的操作类型,数据不变
  22. }
  23. }
  24. const store = createStore(reducer, 10);
  25. const action = {
  26. type: ActionTypes.INCREASE
  27. }
  28. // 得到仓局中当前的数据
  29. console.log(store.getState())
  30. const bindActions = bindActionCreators(ActionCreator, store.dispatch)
  31. // 向仓库分发action
  32. // store.dispatch(ActionCreator.getSetNumberAction(4));
  33. bindActions.getSetNumberAction(3);
  34. console.log(store.getState())