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