redux 源碼詳解

redux 單向數據流的由來

  1. 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對象,該對象包含四個方法;

  1. getState();獲取store中當前的狀態。
  2. dispatch(action): 分發一個action,并返回這個action,這是唯一能改變store中數據的方式。
  3. subscribe(listener): 注冊一個監聽者,它在store發生變化時被調用。
  4. 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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451530.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451530.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451530.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

冒泡排序與快速排序(java實現)

冒泡排序&#xff1a; public class bubbleSort {public static void bubbleSort1(int [] a, int n){int i, j;for(i0; i<n; i){//表示 n 次排序過程。for(j1; j<n-i; j){if(a[j-1] > a[j]){//前面的數字大于后面的數字就交換//交換 a[j-1]和 a[j]int temp;temp a[j…

Python中文編碼問題詳解

中文編碼問題是用中文的程序員經常頭大的問題&#xff0c;在python下也是如此&#xff0c;那么應該怎么理解和解決python的編碼問題呢&#xff1f; 我們要知道python內部使用的是unicode編碼&#xff0c;而外部卻要面對千奇百怪的各種編碼&#xff0c;比如作為中國程序經常要…

PHP環境搭建和Apache HTTP服務器配置

所需軟件: 需要準備Apache HTTP 服務器: http://httpd.apache.org/download.cgi PHP環境下載:http://www.php.net/downloads.php Apache HTTP服務器安裝: 由于最新的 Apache 已經不提供 Windows 的安裝版本了&#xff0c;所以我們這里使用的是解壓版。 下載地址&#xff1a;htt…

ElasticSearch安裝過程中遇到的一些問題

問題1&#xff1a; 安裝Elasticsearch5.X版本&#xff0c;不修改默認配置的情況下&#xff0c;一切還好&#xff0c;能夠正常啟動。但我必須開通外網訪問。然后報錯了&#xff0c;報錯信息如下&#xff1a; ERROR: max file descriptors [1024] for elasticsearch process like…

Java原子操作類AtomicInteger應用場景

參考文章&#xff1a;Java原子操作類AtomicInteger應用場景 感謝作者分享&#xff01;

漂泊的足跡

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 似乎有河一樣的蔓延 流淌過我被陽光翻曬過的身軀 你的足跡 是遙遠的一個小島 從不知名的地方漂泊而來

什么是MD5

MD5是message-digest algorithm 5&#xff08;信息-摘要算法&#xff09;的縮寫&#xff0c;被廣泛用于加密和解密技術上&#xff0c;它可以說是文件的“數字指紋”。任何一個文件&#xff0c;無論是可執行程序、圖像文件、臨時文件或者其他任何類型的文件&#xff0c;也不管它…

selenium使用js進行點擊

WebElement button driver.findElement(By.xpath("/html/body/div[1]/div[3]/h2/div[2]")); JavascriptExecutor js (JavascriptExecutor) driver; js.executeScript("arguments[0].click();", button);當你使用driver原生API如果發現報錯&#xff0c;或…

screenX clientX pageX的區別

screenX:鼠標位置相對于用戶屏幕水平偏移量&#xff0c;而screenY也就是垂直方向的&#xff0c;此時的參照點也就是原點是屏幕的左上角。 clientX:跟screenX相比就是將參照點改成了瀏覽器內容區域的左上角&#xff0c;該參照點會隨之滾動條的移動而移動。 pageX&#xff1a;參照…

進程的五種狀態和線程的六種狀態

參考文章&#xff1a; 進程的狀態轉換和線程的狀態轉換

談談對程序員的培養

這篇文章是我好久以來的想法&#xff0c;有一些感悟&#xff0c;有一些激烈的言辭&#xff0c;我很自豪我就是一名程序員&#xff0c;我希望給程序員或者前程序員們帶來一點啟發。也許你認可我的言辭&#xff0c;也許你不屑我的觀點&#xff0c;無論如何&#xff0c;歡迎談談你…

我記得

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 我記得在農村一片一片金色的稻田 , 碧綠的秧苗 , 我想起有風吹過的時候那金穗一層一層的翻滾 ... 是一際熟悉于往昔的海洋 , 那火黃的…

Python實現文件md5校驗

Linux下校驗文件MD5值&#xff0c;最簡單的方法就是執行md5sum命令 md5sum filename 原本打算用subprocess調用系統命令來獲取md5值&#xff0c; [python] view plaincopy print?import subprocess,shlex cmd "md5sum filename" p subprocess(shlex.split(cmd…

Nexus 安裝(Linux 環境)

一、環境準備 安裝 JDK 1.7 二、下載 Nexus 壓縮文件 下載地址&#xff1a;http://www.sonatype.org/nexus/archived/ 三、上傳壓縮文件 四、解壓縮文件 五、配置環境變量 1、臨時配置 mvn clean package -Dmaven.test.skiptrue -Dmaven.javadoc.skiptrue命令&#xff1a;expor…

android 連接指定wifi

本文牽涉kotlin和rxjava的相關知識 //查詢wifi信息需要申請權限&#xff0c;權限工具類就不要在意了&#xff0c;重點在下面 PermissionUtils.permission(PermissionConstants.LOCATION).callback(object : PermissionUtils.SimpleCallback {override fun onGranted() {//通過授…

英特爾預計5年內將成智能手機芯片大廠

北京時間4月26日早間消息&#xff0c;英特爾預計&#xff0c;英特爾在未來5年內將成為智能手機芯片市場的“重要參與者”。過去10年中&#xff0c;英特爾在這一市場的多次嘗試都未能獲得成功。 英特爾CFO斯泰西史密斯(Stacy Smith)表示&#xff1a;“英特爾并不滿足于成為市場中…

java.util.UnknownFormatConversionException: Conversion = ‘,‘ 解決

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 報錯&#xff1a; 2. 原因&#xff1a; 出錯代碼&#xff1a; if(info.getRiceCount() < 0){ ... } 事實上 對象的riceCoun屬性值…

JAVA中獲取當前系統時間

一. 獲取當前系統時間和日期并格式化輸出: import java.util.Date; import java.text.SimpleDateFormat;public class NowString { public static void main(String[] args) { SimpleDateFormat df new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設置日期格式Sys…

爬蟲中的關于字符串的一些理解

1.基本概念 字符(Character)是各種文字和符號的總稱&#xff0c;包括各國家文字、標點符號、圖形符號、數字等 字符集(Character set)是多個字符的集合 字符集包括&#xff1a;ASCII字符集、GB2312字符集、GB18030字符集、Unicode字符集等 ASCII編碼是1個字節&#xff0c;而Uni…

分布式數據一致性

分布式系統數據一致性問題 感謝作者分享&#xff01;