使用 dva + antd 快速开发react应用
使用 dva + antd 快速开发react应用
版本说明:
注意:dva的版本是0.9.2
$ node -v
v10.2.1 $ npm -v
5.6. $ dva -v
dva-cli version 0.9.
安装cli脚手架:
npm install dva-cli -g
使用脚手架生成应用:
dva new dva_page
建议:在new之前最好安装一下淘宝镜像,因为dva new命令会自动安装node_modules,如果使用npm会比较慢。
npm install -g cnpm --registry=https://registry.npm.taobao.org
安装antd和babel按需加载插件工具:
cd dva_page npm install antd --save npm install babel-plugin-import --D
配置babel-plugin-import:
修改根目录下的.webpackrc文件(注意前面的.,代表linux下的隐藏文件,这是roadhog的webpack配置文件)
{
"extraBabelPlugins": [
["import", {
"libraryName": "antd",
"libraryDirectory": "lib",
"style": "css"
}]
]
}
启动服务:
npm start
此时打开浏览器http://localhost:8000/#/可以看到:
编写routes:
dva默认的页面写在 \src\routes 目录下面:
我们随便引入一个antd组件,写一个demo:
import React, { Component } from 'react';
import { connect } from 'dva';
import { Timeline } from 'antd'; class Demo extends Component {
render() {
return (
<Timeline>
<Timeline.Item>Create a services site 2015-09-01</Timeline.Item>
<Timeline.Item>Solve initial network problems 2015-09-01</Timeline.Item>
<Timeline.Item>Technical testing 2015-09-01</Timeline.Item>
<Timeline.Item>Network problems being solved 2015-09-01</Timeline.Item>
</Timeline>
);
}
} Demo.propTypes = {
}; export default connect()(Demo);
修改路由router.js:
dva的路由配置默认处在 \src\routes 里,我们在里面增加一个路由:
import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import IndexPage from './routes/IndexPage';
import Demo from './routes/Demo'; function RouterConfig({ history }) {
return (
<Router history={history}>
<Switch>
<Route path="/" exact component={IndexPage} />
<Route path="/demo" exact component={Demo} />
</Switch>
</Router>
);
} export default RouterConfig;
现在我们已经可以在http://localhost:8000/#/demo访问新增的页面了。
网络请求:
之前编写的都是静态页面,那么如果有网络请求和数据交互,怎么弄呢?
先完善下 \src\routes\Demo.js :
组件在willMount生命周期会dispatch数据到models层中 namespace 为demo的对象, 触发执行effects中的fetch方法。
import React, { Component } from 'react';
import { connect } from 'dva';
import { Timeline } from 'antd'; class Demo extends Component {
UNSAFE_componentWillMount() {
// dispatch -> effects -> reducer -> 更新this.props
this.props.dispatch({
type: 'demo/fetch', //models里的namespace/effects中的方法名
payload: { //models里的namespace/effects中的payload参数
time: Date.now(),
},
}).catch(err => {
// 异常可以在这里处理,比如网络请求等等
})
} render() {
// console.log(this.props);
return (
<Timeline>
<Timeline.Item>{`${new Date(this.props.new_time)}`}</Timeline.Item>
</Timeline>
);
}
} Demo.propTypes = {
}; const mapStateToProps = (state) => { //把state转换为props
console.log(state);
// 这里会把return的对象作为props传入到Demo这个类里
return state.demo;
}; export default connect(mapStateToProps)(Demo);
在 \src\services\ 中新建文件demo.js :
发送一个网络请求:
import request from '../utils/request'; export function query(params) {
return request('/api/users');
}
在 \src\models\ 中新建文件demo.js :
先引入service文件 /services/demo.js -> 定义namespace为demo -> 在effects定义generator函数 *fetch ,调用services中的请求,将请求结果放入reducers -> reducer将最终结果传入 \src\routes\Demo.js 。
import * as demo from '../services/demo'; export default { namespace: 'demo', state: {
a: 1
}, subscriptions: {
setup({ dispatch, history }) {
},
}, effects: {
// payload 是\src\routes\Demo.js dispatch 过来的参数
*fetch({ payload }, { call, put }) {
// 调用service中的请求,把请求结果存放在result中
let result = yield call(demo.query, payload.time); //如果使用 {参数} ,则是一个对象
result = { data: payload.time / 1000 }; // 因为没有配后台,所以这里result自己模拟数据
// 将result放入reducer中
yield put({
type: 'save', //reducers中的方法名
payload:{
new_time: result.data //网络返回的要保留的数据
}
});
},
}, reducers: {
save(state, action) {
// 将state和effects的put方法的payload传给\src\routes\Demo.js
return { ...state, ...action.payload };
},
}, };
在 /src/index.js 中 注册model:
import dva from 'dva';
import './index.css'; // 1. Initialize
const app = dva(); // 2. Plugins
// app.use({}); // 3. Model
// app.model(require('./models/example').default);
app.model(require('./models/demo').default); // 4. Router
app.router(require('./router').default); // 5. Start
app.start('#root');
最后在浏览器http://localhost:8000/#/demo看到:
总结:
dva的数据流可以概括为:
1. 注册model
2. 使用connect连接mode和page
3. 数据流方向: page(routes) -> (this.props.dispatch) -> model ->model/effects -> (call) -> service -> model/effects -> (put) -> reducer -> page -> (this.props)
最新文章
- ASP.NET web.config中的连接字符串
- svn记录删除
- Spring 3种注入方式
- iOS 判断数组是否为空
- 【Alpha版本】冲刺-Day9
- php的错误级别
- Apple个人(Individual)开发者账号升级公司(Company)开发者账号
- android application plugins framework
- MBProgressHUD ---
- 懒加载 jquery代码
- Help Johnny-(类似杭电acm3568题)
- 基于Redis的CustomerSessionProvider(一)
- 读【10问PHP程序员】 有感
- org.apache.hadoop.security.AccessControlException: Permission denied: user=?, access=WRITE, inode=";/";:hadoop:supergroup:drwxr-xr-x 异常解决
- java面向对象理解
- OJ的初步了解
- 博弈论进阶之SG函数
- 关于javascript中对浮点加,减,乘,除的精度分析
- 关于修改linux hostname的问题,尤其是redhat 7修改hostname的方式
- 转:NSString / NSData / char* 类型之间的转换
热门文章
- 「 Luogu P2657 」 windy数
- 【Python实践-10】用sorted()对列表排序
- 《C语言程序设计(第四版)》阅读心得(三)
- poj 1182用向量的思考模式
- P1072 Hankson的趣味题
- poj-1979 &;&; hdoj - 1312 Red and Black (简单dfs)
- SQL SERVER代理作业删除失败问题
- 安装adt-bundle-windows-x86-20130917时遇到的问题及解决方法
- 洛谷 P3609 [USACO17JAN]Hoof, Paper, Scissor蹄子剪刀…
- IE11 文档模式空白