# Dva 笔记
dva (opens new window)是国内蚂蚁大佬在 react 基础上做的一层封装的轻量框架,深受大家喜欢,而且我司 react 项目也是基于 dva 上写的,所以本文记录学习框架的笔记
# 初始化
起步项目,然后快速构建一个项目。
在
routes
下新建一个产品组件import React from "react"; const Demo = () => { return <h2>111</h2>; }; export default Demo;
在
router,js
添加路由信息import Demo from "./routes/demo"; <switch> <Route path="/demo" exact component={Demo}></Route> </switch>;
# 新建页面
新建一个页面
需要做的事情
首先在routes
下新建容器组件,该组件的作用就是连接UI
组件将数据传给UI
组件
一般参数就是解构props
的dispatch
和 state 的数据
import React from "react";
import { connect } from "dva";
import ProductList from "../components/ProductList";
const Products = ({ dispatch, products }) => {
function handleDelete(id) {
dispatch({
// action在model层中定义,type为namespace+type拼接 payload表示传递参数
type: "products/delete",
payload: id
});
}
return (
<div>
//传递数据给UI组件
<ProductList onDelete={handleDelete} products={products}></ProductList>
</div>
);
};
// 每个参数都是返回一个对象,第一个是state里的数据映射到props
export default connect(({ products }) => ({
products
}))(Products);
接下来就是分别书写model
和UI
组件
// model层组要是操作store中的数据和定义reducers和异步操作的effects
export default{
// 每个state都有key值,调用dispatch时需要拼接到type前
namespace:'products',
state:[],
reducers:{
'delete'(state,{payload:id}){
return state.filter(item=>item.id !== id)
}
},
effects:{
...
}
}
UI
组件 接受容器组件传递过来的事件和数据,然后绑定事件操作数据
import React from "react";
import ProTypes from "prop-types";
import { Popconfirm, Button, Table } from "antd";
const ProductList = ({ onDelete, products }) => {
const columns = [
{
title: "Name",
dataIndex: "name"
},
{
title: "Actions",
render: (text, record) => {
return (
<Popconfirm title="onDelete?" onConfirm={() => onDelete(record.id)}>
<Button type="primary">Delete</Button>
</Popconfirm>
);
}
}
];
return <Table dataSource={products} columns={columns}></Table>;
};
// 校验props
ProductList.prototype = {
onDelete: ProTypes.func.isRequired,
products: ProTypes.array.isRequired
};
export default ProductList;
最后就是定义路由
function RouterConfig({ history }) {
return (
<Router history={history}>
<Switch>
<Route path="/" exact component={IndexPage} />
<Route path="/demo" exact component={Demo}></Route>
</Switch>
</Router>
);
}
# 同步 action 和异步 action
Reducer
在model
分开时
export default {
namespace:'products',
state:[],
reducers:{
'delete'(state,{payload:id}){
return state.filter(item=>item.id !== id)
}
....
}
}
Effect
export default{
namespace:‘todos’,
effects:{
// 定义函数添加上*通配符
* getExpress({ payload }, { call, put }) {
const response = yield call(Services.orderExpress, payload);
yield put({
type: 'queryExpress',
payload: response,
});
}
}
}
底层使用到了redux-saga
实现,语法上使用到了ES6
的generator
函数
主要记住这几个 API
call
用于调用 API 请求
call(func,...args)
const response = yield call(Services.queryStatistic, payload);
put
触发
action
更新数据yield put({ type: 'getStatistic', payload: response, });
takeEvery
监听 action,监听到就调用方法
function* mySaga() { yield takeEvery(actionType, method); }