使用redux middleware完成非同步呼叫
我們團隊在開始使用action->dispatch->reducer其實進入蠻快的
但是當進入到非同步的時候就卡關了
因為要在action creator要處理非同步,如果不使用middleware
我們可能會在action creator
export function addTodo(text) {
setTimeout(function () {
return { type: ADD_TODO, text }
},3000)
}
但是reducer會跟你說錯,因為回來的東西並不是action而是一個function,reducer無法處理,這時候就需要middleware處理了。
我們大概可以把 middleware當作redux流程中的一部分。
action->dispatcher->customized async middleware-> reducer 產生新的state。
============async call sample===========
var Promise = require('bluebird');
var Superagent = require('superagent');
function asyncMiddleware(){
return function store(store){
return function next(next){ //next middleware
return function actionHandle(action){
if (typeof action.ASYNC_CALL !== 'undefined') {
return next(action);
//如果action沒有關鍵字ASYNC_CALL,則直接走下一個middleware
}
var type = action.type;
return new Promise(function promiseHandle(resolve, reject){
//這邊我們使用bluebird的Promise來達成promise
function responseCallback(responseError, response){
//some code error handle or resolve promise
next({
type: type,
response: response
});
resolve(response);
}
//do ajax call
//這邊我們是使用superagent 來get/put/post/delete
Superagent.get(target).query(params).set(header).end(responseCallback);
});
}
}
}
}
=========action creator=================
而我們的action creator就很簡單了
例如下面這個是非同步呼叫載入個人資料
export const LOADED_PROFILE = 'LOADED_PROFILE';
export function loadProfile(params) {
return {
'ASYNC_CALL': { //有此關鍵字 middleware會走 ajax call
type: LOADED_PROFILE,
method: 'get',
target: '/profile/:pid',
params: params
}
};
};
=========component/container===========
import { loadProfile } from 'actions/profile';
class Profile extends Component {
componentDidMount() {
var params = {};//get/post的參數
this.props.loadProfile(params).then(function(result) {
//do something
});
}
}
var mapDispatchToProps = { loadProfile };
export default connect(mapStateToProps, mapDispatchToProps)(Profile);
=========小結=====================
透過這種方式,團隊成員在使用redux流程都會很一致的
action->(middlewares)->reducer->store
不用知道middlewares的細節就可以完成開發
(不過當然我都有解釋給他們聽原理)
=========附註======================
我們是從redux-thunk的source code理解實作方法的
https://github.com/gaearon/redux-thunk/blob/master/src/index.js
只有短短10多行程式碼
redux middleware的說明官方文件跟有人從頭跑過一次redux middleware的中文說明
http://redux.js.org/docs/advanced/Middleware.html
http://huli.logdown.com/posts/294284-javascript-redux-middleware-details-tutorial
沒有留言:
張貼留言