1. 程式人生 > >使用 dva + antd 快速開發react應用

使用 dva + antd 快速開發react應用

pan dem webpack mount api setup require install state

使用 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(),
      },
    })
  }

  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應用