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,并且创建后会自动完成分发。
```json
import { 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())