? 個(gè)人主頁(yè):CoderHing
??? React.js專(zhuān)欄:React.js 再戰(zhàn)Redux
???♂? 個(gè)人簡(jiǎn)介:一個(gè)不甘平庸的平凡人???? 系列專(zhuān)欄:吊打面試官系列??16天學(xué)會(huì)Vue??7天學(xué)會(huì)微信小程序? Node專(zhuān)欄
?? 格言: ?? 路漫漫其修遠(yuǎn)兮,吾將上下而求索??
?? 你的一鍵三連是我更新的最大動(dòng)力!??
?? 本文約 3000? 字,預(yù)計(jì)閱讀需要?15?分鐘 ??
目錄
一、認(rèn)識(shí)ReduxToolkit
認(rèn)識(shí)Redux Toolkit
二、ReduxToolkit重構(gòu)
重構(gòu)代碼 – 創(chuàng)建counter的reducer
重構(gòu)代碼 – 創(chuàng)建home的reducer
store的創(chuàng)建
三、ReduxToolkit異步
Redux Toolkit的異步操作
extraReducer的另外一種寫(xiě)法
Redux Toolkit的數(shù)據(jù)不可變性
四、connect高階組件
自定義connect函數(shù),context處理store
五、中間件的實(shí)現(xiàn)原理
打印日志的需求
修改dispatch
thunk需求
合并中間件
六、React狀態(tài)管理選擇
React中的state如何管理
一、認(rèn)識(shí)ReduxToolkit
認(rèn)識(shí)Redux Toolkit
-
Redux Toolkit 是官方推薦的編寫(xiě) Redux 邏輯的方法
-
在前面我們學(xué)習(xí)Redux的時(shí)候應(yīng)該已經(jīng)發(fā)現(xiàn),redux的編寫(xiě)邏輯過(guò)于的繁瑣和麻煩
-
并且代碼通常分拆在多個(gè)文件中(雖然也可以放到一個(gè)文件管理,但是代碼量過(guò)多,不利于管理)
-
Redux Toolkit包旨在成為編寫(xiě)Redux邏輯的標(biāo)準(zhǔn)方式,從而解決上面提到的問(wèn)題
-
在很多地方為了稱(chēng)呼方便,也稱(chēng)為"RTK"
-
-
安裝Redux Toolkit:
-
Npm install @reduxjs/toolkit react-redux
-
-
Redux Toolkit的核心API主要有以下幾個(gè):
-
configureStore:包裝createStore以提供簡(jiǎn)化的配置選項(xiàng)和良好的默認(rèn)值.它可以自動(dòng)組合你的slice reducer,添加你提供的任何Redux中間件,redux-thunk默認(rèn)包含,并啟用Redux DevTools Extension
-
createSlice:接收reducer函數(shù)的對(duì)象,切片名稱(chēng)和初始狀態(tài)值,并自動(dòng)生成切片reducer,并帶有相應(yīng)的actions
-
createAsyncThunk:接收一個(gè)動(dòng)作類(lèi)型字符串和一個(gè)返回承諾的函數(shù),并生成一個(gè)pending/fulfilled/rejected基于該承諾分派動(dòng)作類(lèi)型的 thunk
-
二、ReduxToolkit重構(gòu)
重構(gòu)代碼 – 創(chuàng)建counter的reducer
-
我們先對(duì)counter的reducer進(jìn)行重構(gòu):通過(guò)createSlice創(chuàng)建一個(gè)slice
-
createSlice主要包含如下幾個(gè)參數(shù):
-
name:用戶標(biāo)記slice的名詞
-
在之后的redux-devtool中會(huì)顯示對(duì)應(yīng)的名詞
-
-
initialState:初始化值
-
第一次初始化時(shí)的值
-
-
reducers:相當(dāng)于之前的reducer函數(shù)
-
對(duì)象類(lèi)型,并且可以添加很多的函數(shù)
-
函數(shù)類(lèi)似于redux原來(lái)reducer中的一個(gè)case語(yǔ)句
-
函數(shù)的參數(shù):
-
參數(shù)一:state
-
參數(shù)二:調(diào)用這個(gè)action時(shí),傳遞的action參數(shù)
-
-
-
createSlice返回值是一個(gè)對(duì)象,包含所有的actions
-
重構(gòu)代碼 – 創(chuàng)建home的reducer
store的創(chuàng)建
-
configureStore用于創(chuàng)建store對(duì)象,常見(jiàn)參數(shù)如下:
-
reduce:將slice中的reducer可以組成一個(gè)對(duì)象傳入此處
-
middleware:可以使用參數(shù),傳入其他的中間件(自行了解)
-
devTools:是否配置devTools工具,默認(rèn)為true
-
-
三、ReduxToolkit異步
?
Redux Toolkit的異步操作
-
在之前的開(kāi)發(fā)中,我們通過(guò)redux-thunk中間件讓dispatch中可以進(jìn)行異步操作
-
Redux Toolkit默認(rèn)已經(jīng)給我們集成了Thunk相關(guān)的功能:createAsyncThunk
-
當(dāng)createAsyncThunk創(chuàng)建出來(lái)的action被dispatch時(shí),會(huì)存在三種狀態(tài):
-
pending:action被發(fā)出,但是還沒(méi)有最終的結(jié)果
-
fulfilled:獲取到最終的結(jié)果(有返回值的結(jié)果)
-
rejected:執(zhí)行過(guò)程中有錯(cuò)誤或者拋出了異常
-
-
我們可以在createSlice的entraReducer中監(jiān)聽(tīng)這些結(jié)果:
-
extraReducer的另外一種寫(xiě)法
-
extraReducer還可以傳入一個(gè)函數(shù),函數(shù)接收一個(gè)builder參數(shù)
-
我們可以向builder中添加case來(lái)監(jiān)聽(tīng)異步操作的結(jié)果:
-
-
Redux Toolkit的數(shù)據(jù)不可變性
-
在React開(kāi)發(fā)中,我們總是會(huì)強(qiáng)調(diào)數(shù)據(jù)的不可變性:
-
無(wú)論是類(lèi)組件中的state,還是redux中管理的state
-
事實(shí)上在整個(gè)JavaScript編碼過(guò)程中,數(shù)據(jù)的不可變性都是非常重要的
-
-
所以在前面我們經(jīng)常會(huì)進(jìn)行淺拷貝來(lái)完成某些操作,但是淺拷貝事實(shí)上也是存在問(wèn)題的:
-
比如過(guò)大的對(duì)象,進(jìn)行淺拷貝也會(huì)造成性能的浪費(fèi)
-
比如淺拷貝后的對(duì)象,在深層改變時(shí),依然會(huì)對(duì)之前的對(duì)象產(chǎn)生影響
-
-
事實(shí)上Redux Toolkit底層使用了immerjs的一個(gè)庫(kù)來(lái)保證數(shù)據(jù)的不可變性
-
為了節(jié)約內(nèi)存,又出現(xiàn)了一個(gè)新的算法:Persistent Data Structure(持久化數(shù)據(jù)結(jié)構(gòu)或一致性數(shù)據(jù)結(jié)構(gòu))
-
用一種數(shù)據(jù)結(jié)構(gòu)來(lái)保存數(shù)據(jù)
-
當(dāng)數(shù)據(jù)被修改時(shí),會(huì)返回一個(gè)對(duì)象,但是新的對(duì)象會(huì)盡可能的利用之前的數(shù)據(jù)結(jié)構(gòu)而不會(huì)對(duì)內(nèi)存造成浪費(fèi)
-
四、connect高階組件
自定義connect函數(shù),context處理store
?
五、中間件的實(shí)現(xiàn)原理
打印日志的需求
-
中間件的目的是在redux中插入一些自己的操作:
-
比如我們現(xiàn)在有一個(gè)需求,在dispatch之前,打印一下本次的action對(duì)象,dispatch完成之后可以打印一下最新的store state
-
也就是我們需要將對(duì)應(yīng)的代碼插入到redux的某部分,讓之后所有的dispatch都可以包含這樣的操作
-
-
如果沒(méi)有中間件,我們是否可以實(shí)現(xiàn)類(lèi)似的代碼呢?可以在派發(fā)的前后進(jìn)行相關(guān)的打印
-
但是這種方式缺陷非常明顯:
-
首先,每一次的dispatch操作,我們都需要在前面加上這樣的邏輯代碼
-
其次,存在大量重復(fù)的代碼,會(huì)非常麻煩和臃腫
-
-
是否有一種更優(yōu)雅的方式來(lái)處理這樣的相同邏輯呢?
-
我們可以將代碼封裝到一個(gè)獨(dú)立的函數(shù)中
-
-
但是這樣的代碼有一個(gè)非常大的缺陷:
-
調(diào)用者(使用者)在使用我的dispatch時(shí),必須使用我另外封裝的一個(gè)函數(shù)dispatchAndLog;
-
顯然,對(duì)于調(diào)用者來(lái)說(shuō),很難記住這樣的API,更加習(xí)慣的方式是直接調(diào)用dispatch;
-
修改dispatch
-
事實(shí)上,我們可以利用一個(gè)hack一點(diǎn)的技術(shù):Monkey Patching,利用它可以修改原有的程序邏輯
-
我們對(duì)代碼進(jìn)行如下的修改:
-
這樣就意味著我們已經(jīng)直接修改了dispatch的調(diào)用過(guò)程
-
在調(diào)用dispatch的過(guò)程中,真正調(diào)用的函數(shù)其實(shí)是dispatchAndLog
-
-
我們可以將它封裝到一個(gè)模塊中,只要調(diào)用這個(gè)模塊中的函數(shù),就可以對(duì)store進(jìn)行這樣的處理:
-
thunk需求
-
redux-thunk的作用:
-
我們知道redux中利用一個(gè)中間件redux-thunk可以讓我們的dispatch不再只是處理對(duì)象,并且可以處理函數(shù);
-
那么redux-thunk中的基本實(shí)現(xiàn)過(guò)程是怎么樣的呢?事實(shí)上非常的簡(jiǎn)單。
-
-
我們來(lái)看下面的代碼:
-
我們又對(duì)dispatch進(jìn)行轉(zhuǎn)換,這個(gè)dispatch會(huì)判斷傳入的
-
-
合并中間件
-
單個(gè)調(diào)用某個(gè)函數(shù)來(lái)合并中間件并不是特別的方便,我們可以封裝一個(gè)函數(shù)來(lái)實(shí)現(xiàn)所有的中間件合并:
-
?
-
我們來(lái)理解一下上面操作之后,代碼的流程
-
-
當(dāng)然,真實(shí)的中間件實(shí)現(xiàn)起來(lái)會(huì)更加的靈活,這里我們僅僅做一個(gè)拋磚引玉,有興趣可以參考redux合并中間件的源碼流程
六、React狀態(tài)管理選擇
React中的state如何管理
-
我們學(xué)習(xí)了Redux用來(lái)管理我們的應(yīng)用狀態(tài),并且非常好用(當(dāng)然,你學(xué)會(huì)前提下,沒(méi)有學(xué)會(huì),好好回顧一下)
-
目前我們已經(jīng)主要學(xué)習(xí)了三種狀態(tài)管理方式:
-
方式一:組件中自己的state管理
-
方式二:Context數(shù)據(jù)的共享狀態(tài)
-
方式三:Redux管理應(yīng)用狀態(tài)
-
-
在開(kāi)發(fā)中如何選擇呢?
-
首先,這個(gè)沒(méi)有一個(gè)標(biāo)準(zhǔn)的答案
-
某些用戶,選擇將所有的狀態(tài)放到redux中進(jìn)行管理,因?yàn)檫@樣方便追蹤和共享
-
有些用戶,選擇將某些組件自己的狀態(tài)放到組件內(nèi)部進(jìn)行管理
-
有些用戶,將類(lèi)似于主題、用戶信息等數(shù)據(jù)放到Context中進(jìn)行共享和管理文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-522002.html
-
做一個(gè)開(kāi)發(fā)者,到底選擇怎樣的狀態(tài)管 理方式,是你的工作之一,可以一個(gè)最好的平衡方式(Find a balance that works for you, and go with it.)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-522002.html
-
到了這里,關(guān)于React | 再戰(zhàn)Redux的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!