一、简介
普通的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>