日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redux 源码详解

發布時間:2023/12/19 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redux 源码详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

redux 單向數據流的由來

  • Flux將應用分成四個部分;
    • view 視圖層;
    • Action 視圖層發出的消息;(改變store里面的數據)
    • Dispatch(派發器)
    • Store (數據層) : 用來存在應用的狀態(數據),一旦發生變動,就要提醒view更新頁面。

    redux單向數據流:

    具體詳情請見阮一峰Flux架構入門

    Action

    • 定義. Action 是把數據從應用(譯者注:這里之所以不叫 view 是因為這些數據有可能是服務器響應,用戶輸入或其它非 view 的數據 )傳到 store 的有效載荷。它是 store 數據的唯一來源。一般來說你會通過 store.dispatch() 將 action 傳到 store。

    • 狹義的Action

    let action = {type: 'ACTION_NAME',... } 復制代碼

    注意: 一般 type 的內容使用 大寫字母+下劃線 的格式.

    • 廣義的Action

      廣義的 action 是指在中間件的支持下,dispatch 函數可以調用的數據類型,除了普通action之外,常見的有 thunk, promise 等。我們用常用的 thunk來舉個例子

      什么叫thunk函數? 具體背景見阮一峰es6標準入門一書第17章Thunk函數的含義.在javaScript中函數將多參數函數替換成單參數的版本,且只接受回調函數作為參數。 例如:

    var Thunk = function(fn){return function(){var args = Array.prototype.slice.call(arguments);return function(callback){args.push(callback);return fn.apply.(this,args);}} }var readFileThunk = Thunk(fs.readFile);readFileThunk(fileA)(callback); 復制代碼Thunk函數版本的action: 復制代碼 (dispatch, getState) => { //在函數體內可以使用 dispatch 方法來發射其他 action//在函數體內可以使用 getState 方法來獲取當前的state } 復制代碼

    ceateStore

    通過該API創建一個store對象,該對象包含四個方法;

  • getState();獲取store中當前的狀態。
  • dispatch(action): 分發一個action,并返回這個action,這是唯一能改變store中數據的方式。
  • subscribe(listener): 注冊一個監聽者,它在store發生變化時被調用。
  • replaceReducer(nextReducer): 更新當前store里的reducer, 一般只會在開發模式中調用該方法。
  • redux middleware

    • Redux 是一個簡單的同步數據流,當分發一個action時,reducer收到action后,更新state并通知view重新渲染。 當action發出后如果想要執行一些別的操作,該怎樣處理,也就是說action發出后沒有立即執行reducer,將redux變成異步. 這時就要借助中間件。

    • redux-middleware的數據流動.

    • 中間件的由來以及原理. 中間件的思想來源于koa. 核心思想:將middleware(函數)進行組合,將當前的middleware執行一遍作為參數傳給下一個middleware去執行。

    原理:

    app.use((ctx, next) => {ctx.name = 'Lucy'next() })app.use((ctx, next) => {ctx.age = 12next() })app.use((ctx, next) => {console.log(`${ctx.name} is ${ctx.age} years old.`) // => Lucy is 12 years old.next() })// ... 任意調用 use 插入中間件app.go({}) // => 啟動執行,最后會調用 callback 打印 => { name: 'Lucy', age: 12 } 復制代碼

    ctx 參數就是 app.go 接受的對象。調用 app.go 其實會調用目標函數 app.callback,但是調用 app.callback 之前我們可以先讓參數 ctx 通過一系列的中間件,最后才會傳遞給 app.callback。

    使用 app.use 插入任意中間件,中間件是一個函數,可以被傳入一個 ctx 和 next;調用 next 的時候會執行下一個中間件。如果不調用 next 會阻止接下來所有的中間件的執行,也不會執行 app.callback。

    這里的app.use()就是一個實現中間件。

    const app = {middleware:[],callback(){console.log(ctx);},use(fn){this.middleware.push(fn);},go(){const reducer = (next,fn,i)=> { fn(ctx,next)}this.middleware.reduceRight(reducer,this.callback.bind(this,ctx))();} } 復制代碼
    • redux的applyMiddleware的源碼.
    function applyMiddle(){(next) => (reducer, initialState) => {let store = next(reducer,initialState);let dispatch = store.dispatch;let chain = [];let middlewarAPI = {getState:Store.getState,dispatch: (action) => { dispatch(action)}}chain = middlewares.map(middleware => middleware(middlewarAPI));dispatch = compose(...chain)(store.dispatch);return {...store,dispatch}}} 復制代碼

    一般這樣應用middleware

    const finalCreateStore = compose(applyMiddleware(...middleware)//DevTools.instrument() )(createStore);const store = finalCreateStore(reducer); 復制代碼

    middleware的一般寫法

    const m1 = store => next => action => {let result = next(action);switch (action.type) {case APP_INCREMENT_LOADING:globalProgressBar.incrementLoading();break;case APP_DECREMENT_LOADING:globalProgressBar.decrementLoading();break;}return result; };export default m1;復制代碼

    注:這里的compose函數請參考app.go或者參考上章FP一節; applyMiddle其實用了2個中間件的思想; 源碼的詳細解釋:

    作者個人博客: http://zhengchengwen.com 歡迎交流

    轉載于:https://juejin.im/post/5b17fd74f265da6e1d6ca9a5

    總結

    以上是生活随笔為你收集整理的redux 源码详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。