一、简介
普通的action处理会自动分派给对应的reducer处理。异步的action会经过Middlewares进行处理,异步完成后再交由对应的reducer处理。
1.Middleware
(1) 截获action
判断action是否是一个promise操作。
(2) 发出action
二、代码实现
举个例子,获取文章列表。action返回的是一个promise,有开始请求列表、获取列表成功、获取列表失败三个action。当ajax异步请求执行后,会发送对应的action,reducer会根据action处理state,ui会渲染对应state的变更。
//redux state
const initialState = {data:null, fetchRebbitListPending:false, fetchRebbitListError:null}// 获取文章列表 action
export function fetchRedditList(args = {}){return dispatch => {// 发送一个开始获取列表事件dispatch({type: FETCH_REDDIT_LIST_BEGIN});// 发送ajax请求,获取数据const promise = new Promise({resolve,reject} =>{const doRequest = axios.get("http://www.reddit.com/r/reactjs.json");doRequest.then(res => {dispatch({type: FETCH_REDDIT_LIST_SUCCESS,data: res.data});},err => {dispatch({type: FETCH_REDDIT_LIST_FAILURE,data: {error:err}});});};return promise;
}// redux reducer
export function reducer(state, action){switch (action.type){case FETCH_REDDIT_LIST_BEGIN:return (data:[action.res.data], fetchRebbitListPending: true, fetchRebbitListError:null);case FETCH_REDDIT_LIST_SUCCESS:return (...state, fetchRebbditListPending: false, fetchRebbitListError:null);case FETCH_REDDIT_LIST_ERROR:return (...state, fetchRebbitListPending: false, fetchRebbitListError:action.data.error);}}// REDUX STORE,指定middle
const store = createStore(reducer, applyMiddleware(thunk));<div><button onClick = {fetchRedditList}>获取文章列表</button>{initialState.fetchRebbitListError && <span>获取文章列表失败</span>}{initialState.fetchRebbditListPending && <span>加载中</span>}{initialState.data && <ul>initialState.data.map(item -> <li>item.title</li)</ul>}
</div>