dva
官方文档 dvajs.com/guide/
dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。
图解
dva路由 内置了react-router
- routes文件夹一般放路由配置的组件
- components一般放通用组件 使用高阶组件withRouter写入路由,完成子组件跳转首页 使用history路由
dva的models
引入models index.js
- namespace 也就是命名空间
- state状态
- reducers处理actions payload也就是dispatch传过来的参数 必须返回一个state
- Effect异步 基于redux-saga
- put是发起一个action给reducers处理
- 异步的话使用call一个参数是接口函数,第二个参数是要传的值
- subscriptions类似于订阅,可以监听路径发生变化然后发起一个dispatch执行reducers的方法,通过方法修改state
models/indexTest.js
import * as apis from "../services/example";
export default {
namespace: "indexTest",
state: {
name: "bbter",
cnodeData:[]
},
reducers: {
setName(state, payload) {
// console.log(payload.data.name);
let newState = JSON.parse(JSON.stringify(state));
newState.name = payload.data.name;
console.log(state);
return newState;
},
setCnodeDataList(state,payload) {
let newState = JSON.parse(JSON.stringify(state));
// console.log(payload)
newState.cnodeData = payload.data
console.log(newState)
return newState
},
testPath(state,payload) {
console.log("用户页")
return state
}
},
effects: {
*setNameAsync({ payload }, { put, call }) {
yield put({
type: "setName",
data: {
name: "超人强",
},
});
},
*testCnode({ payload }, { put, call }) {
let rel = yield call(apis.testCnode);
if (rel.data) {
// yield put
// console.log(rel.data.data);
yield put({
type: "setCnodeDataList",
data:rel.data.data
})
}
},
},
subscriptions: {
haha({ dispatch, history }) {
history.listen(({pathname}) => {
if (pathname === '/user') {
dispatch({
type:"testPath"
})
}
})
}
}
};
routes/indexPage
import React from "react";
import { connect } from "dva";
// import * as apis from "../services/example"
class IndexPage extends React.Component {
handleSetName = () => {
// console.log(this.props)
this.props.dispatch({
// 命名空间加函数名
type: "indexTest/setName",
data: {
name:"猪猪侠"
}
})
}
handleSetNameAsync = () => {
this.props.dispatch({
// 命名空间加函数名
type: "indexTest/setNameAsync",
data: {
name:"猪猪侠"
}
})
}
componentDidMount() {
// apis.testCnode().then((res) => {
// console.log(res)
// })
}
testCnode = () => {
this.props.dispatch({
// 命名空间加函数名
type: "indexTest/testCnode",
})
}
render() {
console.log(this.props.cnodeData)
return (<div>
我是首页
{this.props.msg}
<div>
{this.props.name}
</div>
<button onClick={this.handleSetName}>setName</button>
<button onClick={this.handleSetNameAsync}>setNameAsync</button>
<button onClick={this.testCnode}>testCnode</button>
</div>);
}
}
const mapStateToProps = state => {
return {
msg: "我爱北京天安门",
name: state.indexTest.name,
cnodeData:state.indexTest.cnodeData
}
}
export default connect(mapStateToProps)(IndexPage);
services里一般写接口函数
dva mock测试
mock/testMock.js
module.exports = {
"GET /api/mockdata": (request, response) => {
console.log(request);
response.send({
msg: "登录成功",
});
},
};
在.roadhogrc.mock.js注册mock
export default {
...require("./mock/testMock")
};
在services/example.js注册mock接口
import request from "../utils/request";
// 注册mock接口
export function mockData() {
return request("api/mockdata");
}
routes/indexPages.jsx视图层测试mock