app.model()
执行
app.model(require('./models/news').default);
model/news.js
import {news} from '../services/example.js'
export default {
namespace: 'news',
state: {
list:[1,2,3,4,5,6,7,8,9,10]
},
subscriptions: {
setup({ dispatch, history }) { // eslint-disable-line
},
},
effects: {
*fetch(action, { call, put }) { // eslint-disable-line
console.log("222222222222222222222")
console.log(action)
const data = yield call(news,"777");
console.log(data)
const newslist=data.data.newslist
console.log(newslist)
yield put({ type: 'save' ,newslist:newslist});
},
},
reducers: {
save(state, action) {
console.log(state)
console.log(action)
console.log("hahaha")
return { ...state, list:action.newslist };
},
},
};
产生的结果:
因为namespace属性对应的值 'news',在全局state对象上,添加一个news属性,
局部state:{list:[]}用来初始化全局state的news属性
组件是如何使用全局state呢
举例:Banner组件想要使用全局state的news数据
import { connect } from 'dva';
export default connect(({news})=>({new:news}))(Banner);
connect(fn)(Banner)
其中fn函数的参数是全局state,返回一个json对象,将json对象映射到组件的props属性上
和redux的connect的区别:
dva:connect(mapStateTprops)(app)
redux:connect(mapStateTprops,mapActopnsToProps)(app)
dva自动将store的dispatch映射到组件的props上
关于fn的写法
//参数写成了{news}而不是state相当于{news}=state,解构赋值
//返回值是{news}表示{news:news},给组件的props上添加一个news属性,值是全局state中的news
({news})=>({news})
//实例代码中({news})=>({new:news})表示给props添加一个new(注意没有s)属性,值是全局state中的news
执行流程:
当组件执行
componentDidMount(){
this.props.dispatch({type:'news/fetch',payload:"666666"})
}
*fetch(action,{ call, put })中的action,有dispatch中的action经过了一些封装得到的
执行
yield put({ type: 'save' ,newslist:newslist});
就调用reducers中的save(state, action),state就是全局state对应的news的值
action,就是调用者put({ type: 'save' ,newslist:newslist})传递的action经过封装得到的
代码
const data = yield call(news,"777");
777是传给news函数的参数
export function news(num) {
console.log(num);//777
return request('/api/NewsList.json');
}
data到底是什么
const data = yield call(news,"777");
news函数返回一个promise对象
export default function request(url, options) {
return fetch(url, options)
.then(checkStatus)
.then(parseJSON)
.then(data => {console.log(data);return{data}})
.catch(err => ({ err }));
}
//打印的结果{success: true, newslist: Array(10)}
data就是then函数中return的结果
const data = yield call(news,"777");
console.log(data)
//{ data:{success: true, newslist: Array(10)} }
subscriptions
在app.start()时被执行,(更新时不会执行,可以理解成只执行一次)
官方例子
subscriptions: {
setup({ history, dispatch }) {
// 监听 history 变化,当进入 `/` 时触发 `load` action
return history.listen(({ pathname }) => {
if (pathname === '/') {
dispatch({ type: 'load' });
}
});
},
},