<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ## 數據流向 數據的改變發生通常是通過用戶交互行為或者瀏覽器行為(如路由跳轉等)觸發的,當此類行為會改變數據的時候可以通過`dispatch`發起一個 action,如果是同步行為會直接通過`Reducers`改變`State`,如果是異步行為(副作用)會先觸發`Effects`然后流向`Reducers`最終改變`State`,所以在 dva 中,數據流向非常清晰簡明,并且思路基本跟開源社區保持一致(也是來自于開源社區)。 ![](https://zos.alipayobjects.com/rmsportal/PPrerEAKbIoDZYr.png) ## Models ### State `type State = any` State 表示 Model 的狀態數據,通常表現為一個 javascript 對象(當然它可以是任何值);操作的時候每次都要當作不可變數據(immutable data)來對待,保證每次都是全新對象,沒有引用關系,這樣才能保證 State 的獨立性,便于測試和追蹤變化。 在 dva 中你可以通過 dva 的實例屬性`_store`看到頂部的 state 數據,但是通常你很少會用到: ~~~ const app = dva(); console.log(app._store); // 頂部的 state 數據 ~~~ ### Action `type AsyncAction = any` Action 是一個普通 javascript 對象,它是改變 State 的唯一途徑。無論是從 UI 事件、網絡回調,還是 WebSocket 等數據源所獲得的數據,最終都會通過 dispatch 函數調用一個 action,從而改變對應的數據。action 必須帶有`type`屬性指明具體的行為,其它字段可以自定義,如果要發起一個 action 需要使用`dispatch`函數;需要注意的是`dispatch`是在組件 connect Models以后,通過 props 傳入的。 ~~~ dispatch({ type: 'add', }); ~~~ ### dispatch 函數 `type dispatch = (a: Action) => Action` dispatching function 是一個用于觸發 action 的函數,action 是改變 State 的唯一途徑,但是它只描述了一個行為,而 dipatch 可以看作是觸發這個行為的方式,而 Reducer 則是描述如何改變數據的。 在 dva 中,connect Model 的組件通過 props 可以訪問到 dispatch,可以調用 Model 中的 Reducer 或者 Effects,常見的形式如: ~~~ dispatch({ type: 'user/add', // 如果在 model 外調用,需要添加 namespace payload: {}, // 需要傳遞的信息 }); ~~~ ### Reducer `type Reducer<S, A> = (state: S, action: A) => S` Reducer(也稱為 reducing function)函數接受兩個參數:之前已經累積運算的結果和當前要被累積的值,返回的是一個新的累積結果。該函數把一個集合歸并成一個單值。 Reducer 的概念來自于是函數式編程,很多語言中都有 reduce API。如在 javascript 中: ~~~ [{x:1},{y:2},{z:3}].reduce(function(prev, next){ return Object.assign(prev, next); }) //return {x:1, y:2, z:3} ~~~ 在 dva 中,reducers 聚合積累的結果是當前 model 的 state 對象。通過 actions 中傳入的值,與當前 reducers 中的值進行運算獲得新的值(也就是新的 state)。需要注意的是 Reducer 必須是[純函數](https://github.com/MostlyAdequate/mostly-adequate-guide/blob/master/ch3.md),所以同樣的輸入必然得到同樣的輸出,它們不應該產生任何副作用。并且,每一次的計算都應該使用[immutable data](https://github.com/MostlyAdequate/mostly-adequate-guide/blob/master/ch3.md#reasonable),這種特性簡單理解就是每次操作都是返回一個全新的數據(獨立,純凈),所以熱重載和時間旅行這些功能才能夠使用。 ### Effect Effect 被稱為副作用,在我們的應用中,最常見的就是異步操作。它來自于函數編程的概念,之所以叫副作用是因為它使得我們的函數變得不純,同樣的輸入不一定獲得同樣的輸出。 dva 為了控制副作用的操作,底層引入了[redux-sagas](http://superraytin.github.io/redux-saga-in-chinese)做異步流程控制,由于采用了[generator的相關概念](http://www.ruanyifeng.com/blog/2015/04/generator.html),所以將異步轉成同步寫法,從而將effects轉為純函數。至于為什么我們這么糾結于**純函數**,如果你想了解更多可以閱讀[Mostly adequate guide to FP](https://github.com/MostlyAdequate/mostly-adequate-guide),或者它的中文譯本[JS函數式編程指南](https://www.gitbook.com/book/llh911001/mostly-adequate-guide-chinese/details)。 ### 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'}) }); }, } }); ~~~ ## Router 這里的路由通常指的是前端路由,由于我們的應用現在通常是單頁應用,所以需要前端代碼來控制路由邏輯,通過瀏覽器提供的[History API](http://mdn.beonex.com/en/DOM/window.history.html)可以監聽瀏覽器url的變化,從而控制路由相關操作。 dva 實例提供了 router 方法來控制路由,使用的是[react-router](https://github.com/reactjs/react-router)。 ~~~ import { Router, Route } from 'dva/router'; app.router(({history}) => <Router history={history}> <Route path="/" component={HomePage} /> </Router> ); ~~~ ## Route Components 在[組件設計方法](https://github.com/dvajs/dva-docs/blob/master/v1/zh-cn/tutorial/04-%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1%E6%96%B9%E6%B3%95.md)中,我們提到過 Container Components,在 dva 中我們通常將其約束為 Route Components,因為在 dva 中我們通常以頁面維度來設計 Container Components。 所以在 dva 中,通常需要 connect Model的組件都是 Route Components,組織在`/routes/`目錄下,而`/components/`目錄下則是純組件(Presentational Components)。 ## 參考 * [redux docs](http://redux.js.org/docs/Glossary.html) * [redux docs 中文](http://cn.redux.js.org/index.html) * [Mostly adequate guide to FP](https://github.com/MostlyAdequate/mostly-adequate-guide) * [JS函數式編程指南](https://www.gitbook.com/book/llh911001/mostly-adequate-guide-chinese/details) * [choo docs](https://github.com/yoshuawuyts/choo) * [elm](http://elm-lang.org/blog/farewell-to-frp) ## 原文出處 地址:[Dva 概念](https://dvajs.com/guide/concepts.html#%E6%95%B0%E6%8D%AE%E6%B5%81%E5%90%91)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看