model 包含 5 个属性:
namespace:命名空间.
state:数据的初始化,优先级低于 dva() 的 opts.initialState.
reducers:同步更新state,唯一可以更改state的地方,通过action触发.
effects:异步更新state,不直接修改state,通过action触发.
subscriptions:订阅数据源(数据源可以是当前的时间,服务器的 websocket连接, keyboard输入,geolocation变化,history路由变化等等),然后根据需要 dispatch相应的 action.
代码:
//tags.js
import { request } from 'umi';
// 获取标签数据
const getTags = () => {
return request('/api/tags');
};
export default {
namespace: 'tags', //调用model的时候通过命名空间调用,不要和其他的model重名
//状态,与react的state类似,和redux中的state一样
state: {
tagsList: [],
},
//调用服务端接口,获取数据
effects: {
*fetchTags({ payload, callback }, { put, call }) {
// 获取tags数据
const res = yield call(getTags);
// 更新状态调用reducers,传递数据
yield put({
type: 'setTagsList', //类似于redux中action的type
payload: res,
});
},
},
//更新state
reducers: {
setTagsList(state, action) {
return { ...state, tagsList: action.payload };
},
},
};
ui组件中:
//dva.js
// 创建ui组件
// 创建model
// 将ui组件和model连接
import React, { memo } from 'react';
import { connect } from 'umi';
import { Button } from 'antd';
const Dva = memo((props) => {
// console.log(props);
const { dispatch,tags } = props;
const list =props.tags.tagsList.list || []
console.log(props.tags);
const getData = () => {
dispatch({
type:'tags/fetchTags', //model的名命空间/方法
payload:null
})
};
return (
<div>
<div>Dva的使用</div>
<Button onClick={getData}>获取tags</Button>
{
list.map((item,index)=>{
return <p key={index}>{item.name}</p>
})
}
</div>
);
});
export default connect(({ tags }) => ({ tags }))(Dva);
connect 方法
connect 是一个函数,绑定 State 到 View。
import { connect } from 'dva';
function mapStateToProps(state) {
return { todos: state.todos };
}
connect(mapStateToProps)(App);
model是处理数据的地方,页面是应用数据的地方,那么如何把model和page连接起来,dva提供connect 方法。 这个 connect就是react-redux的connect。 connect 方法返回的也是一个 React 组件,通常称为容器组件。因为它是原始 UI 组件的容器,即在外面包了一层 State。 connect 方法传入的第一个参数是 mapStateToProps 函数,mapStateToProps 函数会返回一个对象,用于建立 State 到 Props 的映射关系。
下面案例的整个数据流向:
通过点击事件getData,dispatch一个action(tags/fetchTags)触发effets里面的fetchTags方法
然后effets里面的fetchTags方法通过yield call去调用请求后端数据的接口getTags(),拿到返回数据data
然后通过reducer(setTagsList)去更新state.