Action
- action是一个plain-object(平面对象)
- 它的proto指向Object.prototype
- 通常,使用payload属性表示附加数据(没有强制要求)
- action中必须有type属性,该属性用于描述操作的类型
- 但是,没有对type的类型做出要求
在大型项目,由于操作类型非常多,为了避免硬编码(hard code),会将action的类型存放到一个或一些单独的文件中(样板代码)。
export const INCREASE = Symbol("INCREASE");export const DECREASE = Symbol("DECREASE");export const SETNUMBER = Symbol('SETNUMBER');
为了方面传递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. action创建函数应为无副作用的纯函数1. 不能以任何形式改动参数1. 不可以有异步1. 不可以对外部环境中的数据造成影响6. 为了方便利用action创建函数来分发(触发)action,redux提供了一个函数`bindActionCreators`,该函数用于增强action创建函数的功能,使它不仅可以创建action,并且创建后会自动完成分发。```jsonimport { createStore, bindActionCreators } from 'redux'import * as ActionCreator from './action/numer-actions'const bindActions = bindActionCreators(ActionCreator, store.dispatch)// 向仓库分发action// store.dispatch(ActionCreator.getSetNumberAction(4));bindActions.getSetNumberAction(3);
这里bindActionCreators根据ActionCreator(就是上面的number-actions.js代码块)和store.dispatch的创建函数,生成一个具有相同属性且属性值完全相似的对象,伺候在使用的时候,不必使用store.dispatch(ActionCreator.getSetNumberAction(4));的调用方式,可以直接使用bindActions.getSetNumberAction(3);
这里我们猜测一下bindActionCreators函数的原理
- 根据
ActionCreator对象,生成一个新的跟ActionCreator对象属性一样的新对象 - 临时保存
ActionCreator的每一个属性的值(这里是一个函数), - 在新对象属性值(也是一个函数)里面,首先调用
ActionCreator的每一个属性,得到action,然后调用store.disatch,把action传入 - 返回新的对象
完整的demo
import { createStore, bindActionCreators } from 'redux'import * as ActionTypes from './action/action-type'import * as ActionCreator from './action/numer-actions'// 假设仓库中仅存放了一个数字,该数字的变化可能是+1或-1// 约定action的格式 {type:'操作类型',payload:附加数据}/*** reducer本质上事宜个普通的函数* @param {*} state 之前仓库中的状态(数据)* @param {*} action 描述要操作什么对象* @return 返回一个新的数据*/function reducer(state, action) {switch (action.type) {case ActionTypes.INCREASE:return state + 1;case ActionTypes.DECREASE:return state - 1;case ActionTypes.SETNUMBER:return action.payload;default:return state;// 如果是一个无效的操作类型,数据不变}}const store = createStore(reducer, 10);const action = {type: ActionTypes.INCREASE}// 得到仓局中当前的数据console.log(store.getState())const bindActions = bindActionCreators(ActionCreator, store.dispatch)// 向仓库分发action// store.dispatch(ActionCreator.getSetNumberAction(4));bindActions.getSetNumberAction(3);console.log(store.getState())
