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

Posted 参与商

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 dva + antd 快速开发react应用相关的知识,希望对你有一定的参考价值。

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

版本说明:

注意:dva的版本是0.9.2

$ 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会比较慢。

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)

 

以上是关于使用 dva + antd 快速开发react应用的主要内容,如果未能解决你的问题,请参考以下文章

react 脚手架create-react-app快速配置开发中常见问题,配合antd按需加载

React Antd HelloWorld

React Antd HelloWorld

Create-React-App创建antd-mobile开发环境

Create-React-App创建antd-mobile开发环境(学习中的记录)

react-router、react-redux、antd(Layout)