通俗易懂地理解Redux

通俗易懂的理解Redux

最近在學習React在學習到有關Redux的狀態管理的時候真的是看了好久但仍是不能說了解的很透徹,通過看了不少篇文章才逐漸對Redux作到了有所瞭解,但願能夠經過這篇文章讓更多不懂Redux的同窗可以理解它,也算是有所做用了,可會被說標題黨了吧。(逃react

雖然咱們能夠經過Redux的官方文檔能夠得知,它是一個JavaScript狀態容器,因此他並非只能和React配合使用,但咱們仍是要先了解React—這個它最常被使用到的場景。git

官方文檔內容:github

Redux 是 JavaScript 狀態容器,提供可預測化的狀態管理。redux

可讓你構建一致化的應用,運行於不一樣的環境(客戶端、服務器、原生應用),而且易於測試。不只於此,它還提供 超爽的開發體驗.api

Redux 除了和 React 一塊兒用外,還支持其它界面庫。 它體小精悍(只有2kB,包括依賴)。服務器

瞭解需求

第一步,咱們先去探索Redux是在什麼狀況下被編寫出來解決什麼問題的,知己知彼,方能百戰不殆。首先咱們先來看下React的特色:網絡

  • React 中有兩個重要的特性: propsstate, props 是父級向下分發的屬性,而 state 則是組件內部本身管理的狀態,而且 React 的數據流是自項而下的,它不存在向上傳遞數據的能力,由於這個特性, React 的數據只可以單向地向下分發或者內部消化。ide

    舉個例子來講的話:React 的數據源是一條河的源頭,它(數據)匯聚成河流向下游地區流動,每一個地區用水(數據)時只能獲得上游流下來的水(props)以及本身經過水庫存的水(state),而上游卻不能讓河流逆流來獲得下游的水資源。函數

  • 一般地,咱們構建的一個 React 組件即實現了某種功能,能夠稱做完整的應用,它有良好的父子關係,數據在這種良好的關係中有秩序的單向流動,但當咱們想讓兩個同級的組件相互交流時,咱們發現他們沒法直接進行交互。BTW, 咱們能夠經過 DOM 來解決這個問題,可這就違背了咱們使用 React 的指望(儘可能地減小直接對 DOM 的操做),咱們能夠經過提高State來解決這個問題,咱們將兩個組件要用的數據放在他們的共同父組件中,而後經過這個父組件 props 分發給兩個組件。學習

  • 此時子組件想要改變父組件的 state 就須要經過 onClick, onChange 等來觸發父組件聲明好得回調,因此至關於父組件要提早聲明好方法來肯定如何改變state, 而後將改變好的state做爲屬性交付給子組件使用,這樣就完成了一次組件間的交互。(概念上的響應)

    可能聽了上面的說明,你仍是雲裏霧裏的,那麼下面我經過一個例子來說解這個概念:

    ​ 咱們假設一個完整的 React 應用是一所學校,一個學生 (組件) 想向他的同桌(同級組件)說下一節是上物理課,可是他不能直接告訴他(不能夠同級組件直接交互),他必須先向他們的班主任(共同的父組件)說:「下一節上物理課」,老師記在了本身的筆記本(state)上,而後老師向每一位同窗發放一張紙(props),上面寫着 」下一節上物理課「,此時他的同桌就知道了,」哦,原來下一節是物理課。「

    ​ 但是有時也有多是一個班的同窗想向另外一個班的同窗傳達某個信息,或者一個班的同窗想向另外一個班的老師傳達某個信息,這個時候咱們找誰呢?哦,咱們想到了學校的掌管者——校長(頂級父組件),此時,一個同窗向校長反應了一個狀況,校長向全校的師生每人發了一個文件,上面寫着這個狀況,這個同窗想傳遞信息的另外一個同窗或者老師就獲取到了這個信息。

Redux的出現

爲了更好地管理state,咱們須要一個庫來做爲專業的頂層 state 分發給所全部的組件, Rudex 出現了。

先來介紹如下 Redux 的主要內容:

  • action: 回調向state發起通知 => 回調的參數

    action 是一個純的聲明,它只提供事件的參數,但不提供任何的邏輯。

  • reducer:根據回調進行處理state => 至關於以前在父級中提早聲明好的方法

    reducer 是一個匹配函數, action 在發送時是發向全局的,因此全部的reducer都會接受到這個action,以後他會判斷這個 action 是否與本身相關,相關就拿走 action 中提供的參數進行邏輯處理來修改 store;若不相關,就什麼也不作。

  • store:就是頂層父級的 state => 全部組件的總狀態

    負責存儲狀態,至關於大腦,它能夠被 React api 回調,經過dispatch方法發佈 action。

咱們接着那個學校的例子講:

​ 但校長日常就有不少事情要處理,若天天大大小小的事情都要校長親自處理,確定是要忙不過來的,因而校長請了一位專業的人員來管理——教導主任(Redux)。教導主任上任便進行了改革:首先,不在把全部的東西都存在校長那裏了,先解放了校長的勞累,而是存在教導主任的信息庫(store)裏。其次,確立了公文格式,不論誰向教導主任彙報信息,都要按格式發公文(action)來確保統一性。再者, 成立了不少部門(reducer),管理不一樣的事務,教導主任接到公文(action)會向全部的部門發送,有關部門看到這個事情是本身管的就去處理,而後向教導主任處的信息庫進行數據修改,不是則什麼也不作,等待其餘通知。

​ 果不其然,自從教導主任接手後,學校的管理更加的有秩序有效率,校長也有空去處理更大的事務,整個學校(React 應用)井井有理地運行着。

優化的應用 react-redux

在咱們的平常應用中,咱們通常不會直接使用兩個庫,而是使用一個 Redux 提供的 React 綁定庫 —— react-redux

react-redux 向咱們提供了兩個東西:

  • Provider 是react-redux向咱們提供的用來做爲 頂層組件 的普通組件。它只須要一個屬性——store,用來存放咱們的頂層 state 而後將它分發給全部 connect 的組件,不論它在哪兒。

  • connect 是一個柯里化(Currying)的函數,它先要接受兩個參數:(數據綁定mapStateToProps 和 事件綁定 mapDispatchToProps),再接收一個參數,就是要綁定的組件自己。

    柯里化:它是把接收的多個參數的函數轉換成接收單一參數的函數的操做。它返回接收餘下的參數而且返回結果的新函數。

    更多有關柯里化的內容能夠看這篇文章,這裏就不作細緻的論述了。

    [翻譯]JavaScript中的柯里化(Currying in JavaScript)

    • mapStateToProps 當咱們構建好 Redux 的應用時,它會自動初始化,但是咱們的 React 組件不知道它的存在,此時咱們分揀出咱們須要的 Redux 狀態中的內容,咱們經過綁定一個函數(參數爲state來返回咱們須要的幾個值)
    • mapDispatchToProps 咱們能夠用已經聲明過的 action 做爲回調,以後注入到組件裏,它的參數是 dispatch ,經過 redux 的輔助方法bindActionCreator綁定全部的 action 以及參數的 dispatch,就能夠在組件裏面做爲函數簡單使用,就不須要手動 dispatch。這個參數是可選的,若是不傳 redux 就會簡單的把 dispatch 做爲屬性諸如給組件,手動當 store.dispatch 使用。

接着學校的例子講:

​ 在高度信息化的今天,教導主任提議,咱們也應該響應信息化(react-redux),因而在校長的支持下,學校接入了信息化管理平臺(Provider),在這個平臺上存儲有全部以前在教導主任處存儲的信息(store),而後他會向每個連上網絡(connect)的教職工發放信息(state)。若是沒有連上網絡(connect),教職工是沒法訪問到信息平臺的,也就不能獲取平臺發佈的信息。可是因爲有些人同窗天天要看教育信息,而有的管理人員要看政務信息,若是都一股腦的把全部信息發給這些人就會很麻煩,因此教導主任決定,學生們連入學生網,管理人員接入政務網,學生網設置他只獲取信息庫中的教育信息(mapStateToProps),而政務網設置他只獲取信息庫中的政務信息(mapStateToProps)。信息管理平臺爲了更加有秩序的管理教職工的公文發佈(action),因此它提早設置了幾種提事務的類型爲教材事務申報、維修事務申報、學籍事務申報等(mapDispatchToProps),提哪一種事務就會直接自動提交到有關部門,不須要部門人員一個一個去看是否是和本身部門相關的了,從教職工到有關部門的工做人員的辦事效率都提升了,全校師生不由讚歎:信息化真好。

雖然這個例子可能不是很合適,但我儘量的用通俗易懂的方式講解了redux的邏輯與內容,相信不懂的你可以有所感悟,而已經懂了的你會有更深一步的認識。:)

小結

作個簡短的總結吧,Redux 說白了就是作了兩件事:

  1. 做爲最頂級的組件,向子組件們分發狀態,來讓 React 組件響應式地渲染。
  2. 監聽子組件的回調,事件有權利回到最頂層影響頂層狀態。

參考文獻:

理解 React,但不理解 Redux,該如何通俗易懂的理解 Redux? ——Wang Namelos

Redux官方文檔

相關文章
相關標籤/搜索