model里其实就是一个对象,我们把这个对象导出
model.js
export default {
namespace: 'test',
state: {
name:'lily'
},
effects: {
*getList({ payload }, { call, put }) {
const res = yield call(getList, payload);
yield put({
type: 'saveList',
payload: res,
});
},
},
reducers: {
saveList(state, action) {
//必须return 否则会报错
return { ...state, age:18,...action.payload };
},
},
};
model 包含 5 个属性:
namespace命名空间,相当于给model取个名字,但是各个model的namespce是不能重复的
state 数据仓库,就是存数据的地方,model里的数据都是存放在这里的
effects:简单来说我们的异步请求就写在这里
reducers:把数据存到仓库(存到state)里的唯一方法,我们修改state里的数据不能直接像this.name='liu'这样去修改,而必须通过调用reducers里的方法
subscriptions:订阅,在这里我的理解就是监听页面的,比如监听到进入了某某页面就让它执行相关代码之类的
model的结构就是这个样子,但是怎么把model和我们写的组件关联起来呢,只需要用到connect就可以啦。
index.js文件里的内容如下
import React from 'react';
import { connect } from 'umi'
class Index extends React.Component {
render() {
return (
<div>
<div className='box'>
</div>
</div>
);
}
}
//通过connect把model和我们写的Index关联起来,test是model的命名空间
const mapStateToProps = (state) =>
//必须返回一个对象
({
...state.test,
...state.test2,
...state.test3,
});
export default connect(mapStateToProps)(Index);
connect是一个高阶函数,高阶函数就是说把一个函数作为另一个函数的参数。connect接受函数mapStateToProps作为参数,connect(mapStateToProps)返回的也是一个函数,然后再把Index作为这个返回的函数的参数。
页面组件与model关联以后我们是这样去使用它的
this.props.dispatch({type: 'test/saveList',payload: {num: 100}})
reducers: {
saveList(state, action) {
//必须return 否则会报错
return { ...state, age:18,...action.payload };
},
},
saveList中的参数 state 和action
state为上次的state。如果连续dispatch了两次reducer,第二次的参数state就是第一次的dispatch之后返回的state,也就是说第一次reducer以后state的值变了,第二次拿到的state就是改变后的state.
action就是dispatch的参数 {type: 'test/saveList',payload: {num: 100}},所以想拿到组件传来的payload参数,要用action.payload。
我们一般把需要传递的数据都放在payload里面,type的值一般是用不到的,所以一般我们会这样写。
reducers: {
saveList(state, {payload}) {
return { ...state, age:18,...payload };
},
},
return 修改之后的state,这里返回什么state的内容就会变成什么
effects
格式为*function(action),action和上面一样,effcts里有很多方法,只要会用call put就可以了
import {getList} from './service'
//异步请求
effects: {
*getList({ payload }, { call, put }) {
//用call来调用接口
const res = yield call(getList, payload);
//用put来调用reducer里的方法 把请求的数据放到state里
yield put({
type: 'saveList',
payload: res,
});
},
},
数据传递
页面或者订阅通过dispatch去调用reducer和effect里的函数,在effect里面去实现services请求,把数据通过reducer放到state里面(reducer操作state里的数据的唯一途径),最后再通过connect吧state和页面关联起来,我们就可以在页面中拿到model里的数据