dva - Route Components

dva實踐

學習react,快速入門的練習

創建引用可以直接使用dva-cli的各項命令快速創建項目.

項目開始前的配置:

  1. 配置antd

    npm i antd --save
    npm i babel-plugin-inmport --save-dev  //按需加載插件
    
    1. .roadhogrc 的"exreaBabelPlugins"里加上語句
      ["import", { "libraryName": "antd", "style": "css" }]

dva-cli 的常用命令
dva g model users
dva g component Mainlayout/Header

使用封裝的loading

安裝:cnpm i dva-loading --save

切換路由:

 dispatch(routerRedux.push({
    pathname:'/users',
    query:{page},
  }))
  • ES6 寫法
import React, { Component, PropTypes } from 'react';
import { Popover, Icon } from 'antd';

class PreviewQRCodeBar extends Component { // 組件的聲明方式
  constructor(props) { // 初始化的工作放入到構造函數
    super(props); // 在 es6 中如果有父類,必須有 super 的調用用以初始化父類信息

    this.state = { // 初始 state 設置方式
      visible: false,
    };
  }
  // 因為是類,所以屬性與方法之間不必添加逗號
  hide() {
    this.setState({
      visible: false,
    });
  }

  handleVisibleChange(visible) {
    this.setState({ visible });
  }

  render() {
    const { dataurl } = this.props;
    return (
      <Popover
        placement="rightTop"
        content={<img src={dataurl} alt="二維碼" />}
        trigger="click"
        visible={this.state.visible}
        onVisibleChange={this.handleVisibleChange.bind(this)} // 通過 .bind(this) 來綁定
      >
        <Icon type="qrcode" />
      </Popover>
    );
  }
}
// 在 react 寫法中,直接通過 propTypes {key:value} 來約定
PreviewQRCodeBar.proptypes = {
  dataurl: PropTypes.string.isRequired,
};

// 在 ES6 類聲明中無法設置 props 只能在類的駐外使用 defaultProps 屬性來完成默認值的設定
// 而在 react 中則通過 getDefaultProps(){} 方法來設定
PreviewQRCodeBar.defaults = {
  // obj
}

export default PreviewQRCodeBar;

  • Stateless 寫法
import React, { PropTypes } from 'react';

// 組件無 state,pure function
const PreviewDevToolWebview = ({ remoteUrl }) => // 箭頭函數,結構賦值
  <webview className={devToolWebview.devToolWebview} src={remoteUrl} />;

PreviewDevToolWebview.proptype = {
  remoteUrl: PropTypes.string.isRequired,
};

export default PreviewDevToolWebview;

// 此類組件不支持 ref 屬性,沒有組件生命周期的相關的時候和方法,僅支持 propTypes
// 此類組件用以簡單呈現數據

理解dva中的數據流

pic

如何來理解呢?

在 web 應用中,數據的改變通常發生在用戶交互行為或者瀏覽器行為(如路由跳轉等),當此類行為改變數據的時候可以通過 dispatch 發起一個 action,如果是同步行為會直接通過 Reducers 改變 State ,如果是異步行為會先觸發 Effects 然后流向 Reducers 最終改變 State,所以在 dva 中,數據流向非常清晰簡明,并且思路基本跟開源社區保持一致。

Action

Action 是一個普通 javascript 對象,它是改變 State 的唯一途徑。無論是從 UI 事件、網絡回調,還是 WebSocket 等數據源所獲得的數據,最終都會通過 dispatch 函數調用一個 action,從而改變對應的數據。** 需要注意的是 dispatch 是在組件 connect Models以后,通過 props 傳入的。**

dispatch({
  type: 'user/add', // 如果在 model 外調用,需要添加 namespace
  payload: {}, // 需要傳遞的信息
});

以上調用函數內的對象就是一個 action。

dispatch 函數

用于觸發 action 的函數,action 是改變 State 的唯一途徑,但是它只描述了一個行為,而 dipatch 可以看作是觸發這個行為的方式,而 Reducer 則是描述如何改變數據的。

dva - Reducer

在 dva 中,reducers 聚合積累的結果是當前 model 的 state 對象。通過 actions 中傳入的值,與當前 reducers 中的值進行運算獲得新的值(也就是新的 state)。需要注意的是 Reducer 必須是純函數

app.model({
  namespace: 'todos', //model 的 namespace
  state: [], // model 的初始化數據
  reducers: {
    // add 方法就是 reducer,可以看到它其實非常簡單就是把老的 state 和接收到的數據處理下,返回新的 state
    add(state, { payload: todo }) {
      return state.concat(todo);
    },
  },
};

dva - Effect

Effect 被稱為副作用,在我們的應用中,最常見的就是異步操作,Effects 的最終流向是通過 Reducers 改變 State

核心需要關注下 put, call, select。

app.model({
  namespace: 'todos',
  effects: {
    *addRemote({ payload: todo }, { put, call, select }) {
      const todos = yield select(state => state.todos); // 這邊的 state 來源于全局的 state,select 方法提供獲取全局 state 的能力,也就是說,在這邊如果你有需要其他 model 的數據,則完全可以通過 state.modelName 來獲取
      yield call(addTodo, todo); // 用于調用異步邏輯,支持 promise 。
      yield put({ type: 'add', payload: todo }); // 用于觸發 action 。這邊需要注意的是,action 所調用的 reducer 或 effects 來源于本 model 那么在 type 中不需要聲明命名空間,如果需要觸發其他非本 model 的方法,則需要在 type 中聲明命名空間,如 yield put({ type: 'namespace/fuc', payload: xxx });
    },
  },
});

dva - Subscription

Subscriptions 是一種從 獲取數據的方法,它來自于 elm。

Subscription 語義是訂閱,用于訂閱一個數據源,然后根據條件 dispatch 需要的 action。數據源可以是當前的時間、服務器的 websocket 連接、keyboard 輸入、geolocation 變化、history 路由變化等等。

import key from 'keymaster';
...
app.model({
  namespace: 'count',
  subscriptions: {
    keyEvent(dispatch) {
      key('?+up, ctrl+up', () => { dispatch({type:'add'}) });
    },
  }
});

dva - Router

這里的路由通常指的是前端路由,由于我們的應用現在通常是單頁應用,所以需要前端代碼來控制路由邏輯,通過瀏覽器提供的 History API 可以監聽瀏覽器url的變化,從而控制路由相關操作。

dva 實例提供了 router 方法來控制路由,使用的是react-router

import { Router, Route } from 'dva/router';
app.router(({history}) =>
  <Router history={history}>
    <Route path="/" component={HomePage} />
  </Router>
);

在 dva 中我們通常以頁面維度來設計 Container Components。

所以在 dva 中,通常需要 connect Model的組件都是 Route Components,組織在/routes/目錄下,而/components/目錄下則是純組件(Presentational Components)。

** 通過 connect 綁定數據 **

比如:

import { connect } from 'dva';
function App() {}

function mapStateToProps(state, ownProps) { // 該方法名已經非常形象的說明了 connect 的作用在于 State -> Props 的轉換,同時自動注冊一個 dispatch 的方法,用以觸發 action
  return {
    users: state.users,
  };
}
export default connect(mapStateToProps)(App);

然后在 App 里就有了 dispatchusers 兩個屬性。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,744評論 3 421
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,879評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,935評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,325評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,534評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,084評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,892評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,322評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,800評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,084評論 2 375

推薦閱讀更多精彩內容