1 回答

TA貢獻(xiàn)2036條經(jīng)驗(yàn) 獲得超8個(gè)贊
dva設(shè)計(jì)動(dòng)機(jī)
用過redux都知道,redux設(shè)計(jì)思想極好,但學(xué)習(xí)概念很多,晦澀難懂,不利于初學(xué)者,并且開發(fā)過程中,牽一發(fā)而動(dòng)全身,往往改一個(gè)小地方,需要在 reducer, saga, action 之間來回切換 ,因此支付寶前端團(tuán)隊(duì)才寫的dva。
dva概念
dva 是基于現(xiàn)有應(yīng)用架構(gòu) (redux + react-router + redux-saga 等)的一層輕量封裝,沒有引入任何新概念!說白了,dva就是為了解決redux現(xiàn)有問題(比如概念多,編寫繁瑣。。。)而設(shè)計(jì)的庫(kù)。您可以把它理解成jquery對(duì)js的封裝!
model方法
dva核心就是 model 方法,用于把 reducer, initialState, action, saga 封裝到一起,其中Model是相關(guān)業(yè)務(wù)操作集合體,是面向業(yè)務(wù)的一個(gè)拆分,因此Model叫做domain model(業(yè)務(wù)模型)更合理些。一般情況model都按照功能模塊劃分,就比如公司項(xiàng)目A,這個(gè)項(xiàng)目包含用戶模塊、產(chǎn)品模塊、活動(dòng)模塊, 那您就可以拆分成三個(gè)Model,分別為user.js、product.js、activitie.js,如果其中一個(gè)模塊過于龐大您可以再細(xì)分,具體依據(jù)自己的業(yè)務(wù)!
dva開發(fā)流程
當(dāng)用戶交互改變數(shù)據(jù)時(shí)會(huì)通過 dispatch 發(fā)起一個(gè) action,同步行為會(huì)直接通過 reducers 改變 state ,異步行為則先觸發(fā) effects 然后再通過 reducers 改變 state,其中 dispatch 是在組件 connect models以后,通過 props 傳入的。該設(shè)計(jì)思路基本跟開源社區(qū)保持一致,現(xiàn)在我們舉例說明下dva開發(fā)流程,同步行為,異步行為都有:
/**
* 這是user組件(Component)
*/
// ES7新標(biāo)準(zhǔn):裝飾器(Decorator)
@connect(state => ({
user: state.user,
}))
// 如果您不喜歡ES7裝飾器,那好辦,我就幫您寫一個(gè)不用的
export default connect(state => ({
user: state.user,
}))(User);
// 如果不喜歡ES7裝飾器,就不要加export default
export default class User extends Component {
componentDidMount() {
const { dispatch } = this.props;
// 獲取數(shù)據(jù),異步行為
dispatch({
type: 'user/fetch',
});
}
componentWillUnmount() {
const { dispatch } = this.props;
// 清空數(shù)據(jù),同步行為
dispatch({
type: 'user/clear',
});
}
render() {
const { user } = this.props;
// 獲取到數(shù)據(jù)了,我要展示到頁(yè)面上
const { userData, } = user;
return (
<div>
用戶數(shù)據(jù):{userData}
</div>
)
}
}
/**
* 這是user model(Model)
*/
export default {
namespace: 'user',
state: {
userData: [],
},
effects: {
*fetch(_, { call, put }) {
// fetchUserData為獲取user數(shù)據(jù)的函數(shù)
const response = yield call(fetchUserData);
yield put({
type: 'save',
payload: response,
});
},
},
reducers: {
save(state, { payload }) {
return {
...state,
...payload,
};
},
clear() {
return {
userData: [],
};
},
},
};
添加回答
舉報(bào)