數據流、我理解爲用戶輸入=> 後臺響應 => 頁面渲染
, dva的作用是中間一環,把響應數據給頁面去渲染,把來自瀏覽器的數據發送給後端服務,這裏面的兩個關鍵問題:
- 如何把用戶輸入數據給dva, dva再傳給服務器
- dva的數據如何傳遞頁面
dva分別提供了兩個關鍵函數dispatch
和connect
來解決這倆問題.
使用dva完成一個例子:
用戶在輸入框內輸入字符串,單擊按鈕時發送給後端,當輸入是1234時,後端返回校驗結果爲true。
- 定義一個dva的model, 文件
src/models/user.js
:
const initializeState = {
};
export default {
namespace: 'user', // 模型的namespace,
state: {
...initializeState
},
effects: {
*login( { payload }, { put }) { // 定義一個login方法,用dispatch訪問時候要指定{type: "user/login"}
const {password} = payload;
yield put({
type: 'save', // payload中的數據會發送給 reducers的save方法
payload: {checkStatus: password === '1234'},
});
},
},
reducers: {
save(state, { payload }) {
return payload
},
},
};
- 在page文件
src/pages/index.js
中寫入:
import {Input} from 'antd';
import { connect } from 'dva';
import { withRouter } from 'umi';
const Login = ({dispatch, loginUser: {checkStatus}}) => { // 給組件函數添加參數,也相當於組件的構造參數,從中解構得到dispatch
const inputOnChange = (event) => {
dispatch({
type: 'user/login',
payload: {
password: event.target.value
}
})
}
return (
<div>
<Input onChange={inputOnChange}/>
<span>校驗結果:{JSON.stringify(checkStatus)}</span>
</div>
)
}
/***
* 將本頁面與`user` 命名空間(namespace)關聯到一起,並將user 命名空間的數據會發送到組件`Login中`;
* mapStateToProps 則可以對 namespace中來的數據重命名到另外一個key上,正常 Login組件接受到的構造參數爲:
* {
* user: {
* checkStatus: false,
* },
* dispatch: ...
* }
* 下面的寫法則修改成:
* {
* loginUser: {
* checkStatus: false,
* },
* dispatch: ...
* }
* 最後的(Login)則指定了user 模型出來的數據送到哪個組件中
*/
export default withRouter(connect(({ user }) => ({loginUser: user})
)(Login));
dva的優勢在於能把數據與多個頁面綁定,增加了編程的複雜性,簡單頁面不必使用。