数据流、我理解为用户输入=> 后台响应 => 页面渲染
, 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的优势在于能把数据与多个页面绑定,增加了编程的复杂性,简单页面不必使用。