1. 什么是redux-actions
redux-actions是一个简化action和reducer创建的一个封装库
常用API函数:
createAction()
handleActions()
2. createAction()
2.1 用法
一般创建Action方式:
export const addTodo = (text) => ({
type: 'ADD_TODO',
text
})
createAction 函数创建Action:
export const addTodo = createAction('ADD_TODO', (text) => (text))
2.2 源码
/**
* 参数不是function调用此函数
*/
function identity(t) {
return t;
}
/**
* 创建action
* @param type action的类型
* @param actionCreator 需要创建的action,函数
* @param metaCreator action的属性
* @returns {Function}
*/
export default function createAction(type, actionCreator, metaCreator) {
/**
* finalActionCreator最终创建的action,
* 判断传进来的参数是不是function,true返回这个函数,false调用identity函数
*/
const finalActionCreator = typeof actionCreator === 'function'
? actionCreator
: identity;
/**
* 返回一个匿名函数
*/
return (...args) => {
/**
*创建的action,只有两个属性
*/
const action = {
type,
payload: finalActionCreator(...args)
};
/**
* 如果给匿名函数传递参数的长度为1个,或者第一个参数元素的类型为Error,那么这么action的error属性为true
*/
if (args.length === 1 && args[0] instanceof Error) {
// Handle FSA errors where the payload is an Error object. Set error.
action.error = true;
}
/**
* 传递到action里面的函数
*/
if (typeof metaCreator === 'function') {
action.meta = metaCreator(...args);
}
return action;
};
}
3. handleActions()
3.1 用法
一般reducer操作state方式:
const defaultState = 'test text'
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'ADD_TODO':
return state
default:
return state
}
}
createAction 提供的 handleActions() 处理 reducer:
const initialState = {
text: 'test text'
}
const reducer = handleActions(
{
['ADD_TODO']: (state, action) => ({
...state,
text: action.payload || ''
})
},
initialState
)
3.2 源码
import handleAction from './handleAction';
import ownKeys from './ownKeys';
import reduceReducers from 'reduce-reducers';
/**
*
* @param handlers 所有的action
* @param defaultState 初始的state
* @returns {Function} 返回reducer
*/
export default function handleActions(handlers, defaultState) {
const reducers = ownKeys(handlers).map(type => {
return handleAction(type, handlers[type]);
});
/**
* 处理过后的reduce
*/
const reducer = reduceReducers(...reducers)
return typeof defaultState !== 'undefined'
? (state = defaultState, action) => reducer(state, action)
: reducer;
}
ownKeys.js
用于判断对象属性的工具
export default function ownKeys(object) {
/**
* Reflect.ownKeys类似于Object.keys(),返回对象中可枚举的属性
*/
if (typeof Reflect !== 'undefined' && typeof Reflect.ownKeys === 'function') {
return Reflect.ownKeys(object);
}
/**
* 返回对象自己(非原型继承的属性)的属性名称,包括函数。
* Object.keys只适用于可枚举的属性,而Object.getOwnPropertyNames返回对象自己的全部属性名称。
*/
let keys = Object.getOwnPropertyNames(object);
/**
* getOwnPropertySymbols
* 返回Symbol类型的属性
*/
if (typeof Object.getOwnPropertySymbols === 'function') {
keys = keys.concat(Object.getOwnPropertySymbols(object));
}
return keys;
}
handleAction.js
操作action
import { isError } from 'flux-standard-action';
/**
* 判断是不是function
*/
function isFunction(val) {
return typeof val === 'function';
}
/**
* 处理action
* @param type action类型
* @param 所有的reducers
* @returns {Function}
*/
export default function handleAction(type, reducers) {
return (state, action) => {
// If action type does not match, return previous state
if (action.type !== type) return state;
const handlerKey = isError(action) ? 'throw' : 'next';
// If function is passed instead of map, use as reducer
if (isFunction(reducers)) {
reducers.next = reducers.throw = reducers;
}
// Otherwise, assume an action map was passed
const reducer = reducers[handlerKey];
return isFunction(reducer)
? reducer(state, action)
: state;
};
}
reduce-reducers
export default function reduceReducers(...reducers) {
return (previous, current) =>
reducers.reduce(
(p, r) => r(p, current),
previous
);
}