使用 dva + antd 快速开发react应用

使用 dva + antd 快速开发react应用

版本说明:

注意:dva的版本是0.9.2css

$ node -v v10.2.1 $ npm -v 5.6.0 $ dva -v dva-cli version 0.9.2

安装cli脚手架:

npm install dva-cli -g

使用脚手架生成应用:

dva new dva_page

建议:在new以前最好安装一下淘宝镜像,由于dva new命令会自动安装node_modules,若是使用npm会比较慢。node

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配置文件)react

{ "extraBabelPlugins": [ ["import", { "libraryName": "antd", "libraryDirectory": "lib", "style": "css" }] ] }

启动服务:

npm start

 

 此时打开浏览器http://localhost:8000/#/能够看到:linux

编写routes:

dva默认的页面写在 \src\routes 目录下面:webpack

咱们随便引入一个antd组件,写一个demo:web

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 里,咱们在里面增长一个路由:npm

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访问新增的页面了。api

网络请求:

以前编写的都是静态页面,那么若是有网络请求和数据交互,怎么弄呢?浏览器

先完善下 \src\routes\Demo.js :babel

组件在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)

相关文章
相关标签/搜索