初識react(五) 資料流終極解決方案 dva(零配置)

言sir發表於2018-09-20

初識react(五) 資料流終極解決方案 dva(零配置)

chaiguanpeng.github.io/

回顧

糾正下,零配置是由umi幫我們實現的,不是dva幫我們做的,但是dva-cli在下一個版本(即dva-cli 1.0)已經內建了umi,簡直開發者福音,有興趣朋友可以體驗下最新版本。

npm i dva-cli@next -g  //安裝下一代dva-cli,內建umi
dva new dvaTest
cd dvaTest
npm start
複製程式碼

我們這裡還是從最基本的dva開始講起,瞭解流程。重點:dva並沒有發明新的概念,全都是以前提到的。只是進行了一層封裝,對redux、saga中的概念很清楚的話,dva就是白給你的,沒有難點,不會來找我。

簡介

  • 基於 redux、redux-saga 和 react-router 的輕量級前端框架。
  • dva是基於react+redux最佳實踐上實現的封裝方案,簡化了redux和redux-saga使用上的諸多繁瑣操作

資料流向

  • 資料的改變發生通常是通過:
    • 使用者互動行為(使用者點選按鈕等)
    • 瀏覽器行為(如路由跳轉等)觸發的
  • 當此類行為會改變資料的時候可以通過 dispatch 發起一個 action,如果是同步行為會直接通過 Reducers 改變 State ,如果是非同步行為(副作用)會先觸發 Effects 然後流向 Reducers 最終改變 State。
    初識react(五) 資料流終極解決方案 dva(零配置)

實現的demo效果

由於dva比較簡單,沒有什麼新概念用例子講解會更明白。最後要實現一個非同步獲取資料 num,然後點選計數器 + num的效果

  • 目錄結構

初識react(五) 資料流終極解決方案 dva(零配置)

1、主入口檔案

import React from 'react';
import dva from 'dva';
import Counter from './Counter';
//dva是一個函式,通過執行它可以拿到一個app物件
let app = dva();
//一個模板就是一個狀態,然後把reducer和狀態 寫在一起了,
//新增一個模組
app.model({
   xxxx
});
//引數是一個函式,此應用本身就是要渲染函式的返回值
app.router(() => <Counter />);

//本質是啟動應用,就是通過app.router獲取元件,並且通過ReactDOM渲染到容器內容
app.start('#root');

複製程式碼

以上是最基本的dva的主入口檔案,簡單的3個API,app.model、app.router、app.start,就已經講react、redux-router、redux、redux-saga整合一起,簡直開發者福音。我們講解下怎麼用

  • dva是一個函式,通過執行它可以拿到一個app物件
  • app.model()新增一個模組,下面重點講解
  • app.router()接受函式,然後渲染函式返回值
  • app.start('#root'),通過app.router獲取元件,然後通過ReactDom渲染到容器
1.1、app.model()用法
  • 接受一個物件,把state、reducers、effects全部寫在這,便於維護。
app.model({
    //名稱空間。因為一個應用會有很多個模型,每個模型要有一個名字
    namespace: 'counter',
    //此名稱空間的預設狀態
    state: { current: 0, highest: 0 },
    //它是用來接收action,修改倉庫狀態的
    reducers: {
        save(state, action) {
            return { current:state.current+action.payload  };
        }
    }
});

複製程式碼

看見這些名詞應該很熟悉吧

  • namespace名稱空間,我們需要給模型一個名字
  • state=>狀態,就是redux中的狀態
  • reducers=>處理器,就是redux中的處理器

在強調遍,dva沒有發明新的概念,只是進行了一層封裝。讓狀態更利於維護

2、編寫Counter.js元件

import React from 'react';
import { connect } from 'dva';
class Counter extends React.Component {
    render() {
        return (
            <div className="container">
                <div className="current">
                    當前記錄:{this.props.current}
                </div>
                <div className="addButton">
                    <button onClick={() => this.props.dispatch({ type: 'counter/save',payload:2 })}>+</button>
                </div>
            </div>
        )
    }
}
export default connect(
    state => {
        return state.counter;
    }
)(Counter);

複製程式碼

不過多解釋,有2個地方需要注意:

  • 元件內部派發動作時,type:'counter/add',前面多了counter(名稱空間)
  • connect時的狀態是總的狀態,需要制定下需要counter的狀態

初識react(五) 資料流終極解決方案 dva(零配置)

目前為止,dva流程已經跑通了,是不是很簡單,我們測試下是否能點選加2

初識react(五) 資料流終極解決方案 dva(零配置)

完美實現,說好的非同步呢,接下來我們用express編寫一個簡單介面

3、編寫服務端介面 server.js

我們用express編寫簡單介面,不講解express用法。 express直通車

let express = require('express');
let cors = require('cors'); //解決跨域的包
let app = express();
app.use(cors()); //使用中介軟體cors
app.get('/amount', function (req, res) {
    res.send({ num: 5 });
});
app.listen(3000);
複製程式碼
  • 接下來啟動服務,看下效果
    初識react(五) 資料流終極解決方案 dva(零配置)

4、客戶端發請求獲取資料

由於案例比較簡單,都寫在了src/index.js中

function getAmount() {
    return fetch('http://localhost:3000/amount', {
        headers: {
            "Accept": "application/json"
        }
    }).then(res => res.json());
}
複製程式碼

5、在app.model中新增effects(副作用) (就是redux-saga中的effects)

  effects: {
        //表示這是一個generator effect=redux-saga/effects
        *add(action, { call, put }) {
            let { num } = yield call(getAmount); 
            yield put({ type: 'save', payload: num });
        }
    },
複製程式碼

先非同步獲取資料,然後再派發動作修改狀態,接著重新整理檢視

6、對應的元件新增一個非同步記數的按鈕

<button onClick={() => this.props.dispatch({ type: 'counter/save',payload:2 })}>同步加2</button>
<button onClick={() => this.props.dispatch({ type: 'counter/add' })}>非同步記數</button>
複製程式碼
  • 增加了一個非同步計數按鈕,會派發add動作型別。
  • add型別被effects(副作用)中的add監聽到,執行 getAmount()非同步獲取資料
  • 拿到資料後派發save動作,被reducers處理
  • 頁面重新整理

測試結果

初識react(五) 資料流終極解決方案 dva(零配置)

完結

dva 簡化了redux和redux-saga使用上的諸多繁瑣操作,便於我們開發,可維護性也更高,配合umi使用,號稱零配置,下篇文章會講解dva+umi使用

相關文章