聽過Redux很久了,不過真的開始學大概在一個月前,學會Redux以後我用一週多的時間重構了以前純React寫的一個小項目。學習的過程當中心態變化很大,可是最終真的感受若是再寫複雜一點的項目,我應該不再會直接用state管理全部狀態了。Redux真的刷新了個人狀態管理觀。javascript
本文的寫做目的在於讓那些一直在使用React,可是尚未使用Redux管理複雜應用狀態的同窗瞭解Redux的核心思想並可以更加平滑的學習使用Redux。html
快雙十一了,忽然想到一個比喻來解釋爲何會有React這類框架的存在,爲何咱們要使用Redux,話說之前使用jQuery不也挺快樂的嘛。前端
想一想現代物流系統發展的不一樣階段,咱們寄一件東西的過程,java
沒有物流系統時:react
打包準備好要送出去的東西;git
出門乘車到達朋友家,把東西送給朋友;github
很直接很方便,很費時間,送東西的距離有限(同城?);編程
出現了各大物流公司時:redux
打包準備好要送出去的東西;api
出門到距離家最近的物流公司,填寫物品,收件人等基本信息;
物流公司替你送物品到你的朋友處,本身能夠回家作別的事情了;
多了一箇中介,要付必定的運送成本,可是東西能夠送到遠在幾千千米以外的其它人了,用一點點錢節約了本身寶貴的時間,完成了之前咱們不可能作的事情;
沒錯,沒有物流系統時對應的就是之前使用jQuery的前端階段,作一件事情很直接,若是隻是送快遞給一個特別近的人,那固然是很是方便。就算你要從北京送一個東西到上海,在這個階段你也能夠實現,可是須要付出的代價就太大了。
而出現了各大物流公司對應的就是使用React等框架的階段,學習React須要付出成本,若是你只須要作簡單的事情(好比說你想把東西送給你的鄰居),那使用此類框架其實顯得特別累贅,把簡單的事情複雜化了,可是若是你想作複雜一點的事情(同時寄禮物給三個不一樣城市的人),那麼選擇快遞公司是不會錯的。
那麼React和Redux的關係又該如何理解呢?
我以爲咱們能夠把React
好比爲一家自建快遞系統的公司(京東?),在必定範圍內,它的快遞系統已經足夠好了(部分一二線城市一天內直達),可是要管理這個日益複雜的快遞系統,須要公司付出巨大的成本。
Redux
能夠看作業內最好的第三方快遞系統(順豐?),使用它比較貴(學習成本稍微有點高),可是他到達全國主要城市都會特別快,若是你是一個電商老闆,採用這個第三方物流系統以後,你只須要關注於本身的貨物,幾乎不用再去關心物流怎麼辦了。
不一樣於順豐每一次寄貨都要那麼高的價格,redux是一個學習一次,就能夠免費寄貨的優秀第三方快遞系統,那咱們固然要解散本身的物流公司來採用這個第三方的選擇的。不過話說回來,學習是須要有成本的,因此是直接使用React仍是學習Redux再使用,這是你一個你須要依據你本身項目的實際狀況做出選擇的事情。
不過這個例子可能並不足夠合適,Redux作的不只僅是管理原來React裏state裏面的狀態。Redux其實能夠接管咱們的app裏全部的數據。接下來咱們具體看看Redux究竟作了什麼。
咱們經常聽到一種說法,「Redux是一個很是好的狀態管理器」,那究竟什麼是狀態呢。
想一想咱們平時看的網頁,app,或者任何其它和咱們有交互的東西,咱們感受到交互的發生是由於界面依據咱們的行爲做出了反饋,界面全部的改變,其實均可以看做是狀態的改變,或者說界面會改變是由於咱們的某個行爲(事件)(click
,drag
,move
...)觸發了某個函數,函數形成了狀態的改變,進而改變了界面。
如此看來,不管是顯示隱藏這種可見的狀態,仍是從服務器獲取更多的數據,這些均可以看作是狀態,而這些狀態就是咱們的Redux要管理的。
換一個可能比較專業一點的說法吧,狀態包括
API State;(數據)
UI State;(UI的表現形式)
爲了更好的展現Redux的好,咱們回顧一下前端的狀態管理史(稱爲史其實並不合適,如下三種模式如今都有大量人在使用)。
中古
jQuery 時期
咱們使用諸如$(element).addClass('active')
這樣的語句來改變狀態;
對簡單的應用來講,這樣寫簡單明瞭,可是狀態一多一複雜就亂了,並不存在一個專門管理狀態的地方;
近代
React內部管理狀態時期
咱們引入了state
來管理組件狀態,界面想顯示不一樣的樣子,咱們經過各類函數來改變state
來實現
已經存在一個專門管理狀態的state
(對象,數組)了,對大部分應用來講,用state
來管理狀態已經足夠了,可是應用複雜了會使得狀態
現代
引入Redux等狀態管理機制時期;
redux使用一個store
來全局管理各類狀態,提供一些不算複雜的api來專門管理狀態;
能夠管理更加複雜的狀態,經過redux的管理,狀態的改變變得更加清晰,可預測,redux
中的狀態是一個只讀屬性,經過必定的方法,能夠回到已經經歷過的某個狀態(時間旅行);
(這裏沒有說到MVC等機制有興趣的同窗能夠看這篇文章作進一步對比了解,基本觀點是MVC當然很好,可是配合React使用時,性價比不是那麼高了。)
上面已經說了Redux管理狀態特別好,那Redux到底是如何管理狀態的呢?狀態分爲UI State 和 API State,Redux針對這兩部分也提供了兩種方法
爲改變已有的狀態提供了方案;
爲異步獲取新的數據提供了方案;
仍是用圖片來講明更加清楚
下圖說明了Redux和React的狀態流分別是怎麼樣的;
下圖說明了使用Redux管理狀態爲何是可預測的
Redux的數據是如何流動的其實也是理解Redux的好處的關鍵部分之一,簡單來講每一個事件會發送一個action,action經過dispatch觸發reduce,直接依據舊的state生成一個新state替代最頂層的store裏面原有的state。
有一篇文章以漫畫的形式把這個講的特別透A Cartoon intro to redux
說了這麼多使用redux管理狀態的好處,可是你看到這裏可能依舊不知道如何使用redux
,不要着急,我和你分享個人Redux學習經驗。
若是你已經能很熟練的使用React,我以爲學習Redux須要瞭解的基礎知識,你應該都已經瞭解了。具體說來主要有如下內容;
React(Redux是flux架構的實現,雖然其也能夠配合其它框架使用,可是它和React可能仍是更配一些吧);
基礎的ES6知識(Redux重視函數式編程,會使得編程的結構看起來更加簡潔);
用了ES6(甚至ES7)固然免不了要學習使用Webpack,Babel等;
還有一點,我以爲學習編程應該不怕折騰,使用Redux管理一個狀態可能須要改好幾個文件裏的代碼才能實現,編程再也不顯得那麼直接(好比 經過connect.js
調用action.js
裏的某個action
,並依據這個action
觸發reducer.js
裏面的某個reducer
函數依據現有的state
,建立一個新的state
),redux把一些操做給抽象化了,若是思惟沒有跟着改變,會讓人有一種redux文檔裏面的東西我都看懂了,可是我怎麼就是編不出來呢?那種痛苦的感受。
網上關於Redux的教程特別多了(官方文檔寫的特別好),學習新概念是比較惱人的一個過程,因此我仍是會對Redux提供的api作一個簡潔的描述,而後我會把我這段時間看過的我以爲比較好的文章的連接放在下面以供你們參考。
state
:app中的狀態存放的地方,而且state是隻讀的,不一樣於React,Redux中state的更改,實際上是建立了一個全新的state;
action
:是一個對象,做用和他的名字同樣,用來代表,你想要作的那件事情,該對象的屬性type,用來標記,你要作的事情;
reducer
:是一個函數,接收當前state,和一個action做爲參數,依據action基於當前的state
生成新的state
;
dispatch
:推送某個action
給reducer
;
action creater
:一個建立action
的函數,返回一個action
對象;
異步action
:返回一個函數,和中間件配合能夠很容易的實現異步操做;
store
:能夠理解爲state
的家,全局只有一個,有如下方法
getState()
:獲取當前的state樹;
dispatch(action)
:觸發一個action,建立state;
subscribe(listener)
:
replaceReducer(nextReducer)
combineRedecers(reducers)
:當咱們的應用比較複雜的時候,咱們可能會分開寫好幾個reducer
,這個函數的做用就是把這些單獨的reduce合併爲一個大的reduce,須要注意的是咱們的state的結構和咱們的各個reducer
是一一對應的。
applyMiddleware(...middlewares)
:告訴redux咱們會用到那些中間件,好比說要用到基礎的異步,咱們會用到thunk中間件;
let store = createStore( comReducer, applyMiddleware(thunk) );
bindActionCreators(actionCreators, dispatch)
:綁定actionCreator
和dispatch
以供直接使用;
redux只是管理狀態的一種方法,真的用在React裏,使用做者提供的一個工具react-redux
會更加方便,其api很簡單,主要有如下幾個;
<Provider store>
,嵌套在React組件的最外層,所以能夠把state傳給全部的組件(利用了React的context
);
把React組件分爲容器組件和UI組件兩類,容器組件管理邏輯,UI組件管理顯示效果兩者經過connect
方法鏈接,容器組件通常由UI組件依據connect
生成;
mapStateToProps()
,存在於容器組件中,針對UI組件的各狀態(依據state
,或者父組件的props
)生成;
mapDispatchToProps()
,存在於容器組件中,針對UI組件中的各可能改變state的事件定義的一系列的函數,依據props
傳給UI組件;
Redux還有一個很是酷的工具,讓咱們能夠實時看到當前的state,使用redux不可不用啊。
酷酷的工具redux devtools
在弄懂了一些關鍵的核心概念之後,若是仍是不知道怎麼寫,就模仿官方給的多個例子針對本身的需求敲寫一次吧。模仿了兩個例子就確定明白了。
Redux也有本身的小生態,理解的一些技術輔助Redux更加方便的實現狀態管理,其中有一些是下一步我特別想了解的好比說immutable-js,reselect,normalizr,固然由於學習了Redux,因此我也想對函數式編程作進一步理解,以前找到了一本很是好的關於函數式編程的書mostly-adequate-guide,分享給你們,你們一塊兒學習。