dva是一個狀態管理工具,整合了redux,redux-saga,react-router,fetch等框架,目前只能用於react的狀態管理
1. dva的models
dva的主要作用還是整合了redux,redux-saga的多檔案的分散的寫法,將state,reducers,effects這些常用的狀態
處理方法集中在一個model中,其形式如下:
import * as userService from '../services/userService' export default { namespace: "users", state: { list:[] }, reducers: { save(state, {payload:{data}}) { state.list = data; return {...state} }, removeItem(state, {item}) { state.list = state.list.filter(function (lItem) { return item.id !== lItem.id }); return{...state} } }, //effects指的是涉及到非同步請求的方法。通常用來呼叫服務獲取資料。 //這裡要注意如果effects的方法名與reducers中存在重複的話容易造成死迴圈。 effects: { * fetch(payload,{put, call}) { const data = yield call(userService.fatchData); yield put({type: "save", payload: data}) }, * fetchRemoveItem({item},{put,call}){ const result = yield call(userService.fetchRemoveItem,item.id); if (result){ console.log(true); yield put({type:"removeItem",item}) }else{ console.log(false); } } }, subscriptions: { setup({dispatch}) { dispatch({type: 'fetch'}) } } }
要在全域性的app中註冊model
app.model(require('./models/users').default);
2. dva的models的幾點說明
namespace: 全域性狀態的屬性,通過global.namespace來訪問對應model的state
reducers: 同步修改狀態的方法
effects: 非同步修改狀態的方法,effects中使用的還是generator,與redux-saga中的呼叫完全一致,
不能直接呼叫reducers中的同步方法,通過put({'reducer方法名',payload})的形式來
呼叫reducer中的方法
subscriptions: subscription 是訂閱,用於訂閱一個資料來源,然後根據需要 dispatch 相應的 action。
在 app.start() 時被執行,資料來源可以是當前的時間、伺服器的websocket 連線、
keyboard 輸入、geolocation 變化、history 路由變化等等
這個結構與vuex的結構十分類似
state -> reducers -> effects 對應 state -> mutations -> actions
3. dva中的狀態傳遞
依然採用react-redux的方法,用connect,mapStateToProps來解決
4. dva中的全域性事件
dva中提供了一下全域性的事件,來解決註冊和攔截問題
const app = dva({
history,
initialState,
onError,
onAction,
onStateChange,
onReducer,
onEffect,
onHmr,
extraReducers,
extraEnhancers,
});
onError: effect 執行錯誤或 subscription 通過 done 主動拋錯時觸發,可用於管理全域性出錯狀態
onAction: 在 action 被 dispatch 時觸發,用於註冊 redux 中介軟體
onStateChange: state 改變時觸發,可用於同步 state 到 localStorage,伺服器端等
onReducer: 封裝 reducer 執行,全域性攔截reducer
onEffect: 封裝 effect 執行,全域性攔截effect
onHmr: 全域性處理熱替換
extraReducers: 指定額外的 reducer
extraEnhancers: 指定額外的 StoreEnhancer
參考:http://www.cnblogs.com/axel10/archive/2018/03/12/8548305.html