1.下載下傳插件
2.項目結構

3.<code>redux</code> 适用于 多互動,多資料源,複雜程度高的工程中。
使用 redux 之前,基本的東西還是要都懂的,資料流向介紹:
Action:行為。它的作用就是将我們更新元件的 狀态(state) 的每個動作抽象為一個行為,它有一個必須的參數 type,定義了 Action(行為) 的名稱,其他參數可自定義。寫法:
因為 Action 是個對象,是以,我們需要建立這個對象,那建立這個對象的方法叫做 ActionCreator,寫法:
Reducer:reducer 的作用就是根據傳入的 Action行為和舊的 state對象,傳回一個新的 state ,然後元件會根據 state 重新整理。當我們确定了元件的 state 對象結構 和 action 行為的時候就可以編寫 reducer 中的内容。寫法:
當然我們的工程中可能會有多個 reducer 的情況,通過 combineReducers 可以将多個 reducer 合成統一管理。
Store:當 reducer 傳回了新的 state 後,這個 state 怎麼傳到元件和存儲就成了問題,redux 就是把這個狀态統一放到 store 中進行管理。
上面的代碼根據 reducers 建立了一個 store方法集(它并不是一個對象),然後再 store 中提供一些方法供我們使用:
注:
另外 redux 有 5個 全局方法:
(1)createStore:建立一個redux store 來存儲應用中所有的state,應用中隻能存在一個 store
(2)combineReducers:把多個reducer函數作為value的object,合并成一個reducers函數,然後就可以通過reducers調用各個子reducer,state 對象的結構由傳入的多個 reducer 的 key 決定。
(3)...middlewares:每個 middleware 接受 store 的 dispatch 和 getState 函數作為命名參數,并傳回一個函數。
1.該函數會被傳入被稱為 next 的下一個 middleware 的 dispatch 方法,并傳回一個接受 action 的新函數,這個函數可以直接調用 next(action),或者在其他需要的時刻調用,也可不調用。
2.調用鍊的最後一個 middleware 會接受真實的 store 的 dispatch 方法作為 next 參數,并結束調用鍊。是以 middleware 的函數為 ({ getState, dispatch }) => next => action。
3.傳回值:一個應用了 middleware 後的 store enhancer。這個store enhancer 就是一個函數,并且需要應用到 createStore。它會傳回一個應用了 middleware 的新 createStore。
(4)bindActionCreators:把 actionCreators 轉曾擁有同名 keys 的對象,讓 dispatch 把每個 actionCreator 包裝起來,這樣就可以直接調用它們。唯一使用 bindActionCreators 的場景是需要把 actionCreator 往下傳到一個元件上,卻不想讓這個元件察覺到 redux 的存在,而且不希望把 redux store 或者 dispatch 傳給它。
傳回值:一個與原對象類似的對象,隻不過這個對象中的每個函數值都直接 dispatch action。如果傳入的是個函數,傳回的也是函數。
(5)compose(...fuctions):當需要多個 store 增強器 依次執行的時候使用它。compose 在應用常見的兩個用法:
參數1(arguments):合成多個函數。每個函數接受一個函數作為參數,然後傳回一個函數。
參數2(Function):從右往左把接受到的函數合成後的終極函數。
換張圖了解:
(1)首先,根據 redux官方文檔的示例 我們可以看出官方建議我們将元件分成 containers(容器元件)、components(子產品視圖元件)、redux 三大塊。是以我們這邊檔案的層級如下圖所示:
(2)接着,我們再來完成視圖部分,然後根據視圖部分确定哪些需要 redux 支援,再來生成相應的 <code>action</code> 與 <code>reducer</code> 檔案。
1.首先,是 Main 檔案,作為我們的容器元件放到 containers 檔案夾内,Main 中的内容:
Main.js
那裡面我們需要将 Text 作為視圖元件獨立出來,是以将視圖元件 TestText 放到 components 檔案夾中,TestText 中的内容:
TestText.js
(3)視圖部分我們搭建完成,那麼我們接着就是确定需要哪些 action(行為),那前面提到了,我們是要點選按鈕的時候讓文字發生改變,也就是說我們目前需要一個改變文字的行為,那我們就将這個行為命名為 CHANGE_TEXT,那麼我們需要初始化這個 action 這個對象,也就是前面我們提到的 action creator:
action.js
(4)action 檔案配置完畢後,我們就可以根據需求來編寫 reducer 檔案了,reducer 檔案就是起到更新 state 的作用嘛,是以我們将改變 文字 的邏輯放到這裡,當reducer 比對到目前的點選行為為 CHANGE_TEXT 時,就執行相應的操作,傳回一個新的 state 給我們使用,如果比對不到,那麼就預設傳回一個不變的新 state:
reducer.js
(5)配置完 <code>action</code> 和 <code>reducer</code> 兩個檔案後,緊接着我們就可以根據 <code>reducer</code> 來初始化 <code>store</code> 了:
store.js
(6)<code>redux</code> 的東西已經都配置完成了,接着就剩下使用了,是以接下來要解決的問題就是怎麼發送行為,怎麼接收 <code>state(狀态)</code>,上面提到了,<code>store</code> 其實是個方法集,我們的 <code>發送行為 和 接收狀态</code> 方法都在 <code>store</code> 中,是以隻要拿到 <code>store</code>,是以隻要拿到 <code>store</code> 就能進行這兩個操作。
(7)那怎麼拿到 <code>store</code> 呢?在官方文檔中,清楚地告訴我們,<code>Provider</code> 的任務就是将 <code>store</code> 傳給 <code>connect</code>,而 <code>connect</code> 的作用是将我們的元件進行第二次包裝,将操作資料的函數和資料的狀态包裝到 <code>props</code> 中,是以,首先,我們需要對我們的 <code>Main</code> 檔案進行第一次包裝,我們再建立一個 <code>index</code> 檔案來對 <code>Main</code> 檔案進行包裝:
Index.js
(8)包裝完成後,我們的 Main 檔案就可以獲得 store 了,那接着就是進行第二次包裝了,通過 connect 生成新元件:
(9)到這裡,我們的 新元件 就能夠收發資料了,那怎麼接收和發送呢,别急,我們接着就來完成 mapStateToProps(更新回調) 和 mapDispatchToProps(發送行為) 兩個方法。首先,我們需要通過 mapDispatchToProps 來發送行為,然後通過 mapStateToProps 來監聽 state 的變化,這邊我們需要發送的行為 type 是 CHANGE_TEXT,當發送行為之後,reducer 就會去比對 行為的類型,進行相應操作:
(10)當 reducer 接收到我們觸發的 行為 并進行一系列處理後,最終會傳回一個新的 state,那麼 就會自動調用 mapStateToProps 來告訴系統,state 被操作了,那麼我們就可以通過 mapStateToProps 來擷取 state 狀态:
(11)那麼接下來我們 怎麼改變文字 呢?前面提到,connect 作用就是生成一個新的元件,新的元件的 props 中包含了資料擷取和操作資料的函數,是以我們需要讓 子元件拿到容器元件中的 props,然後在 子元件 中通過 props 就可以拿到上面 定義的 value 和 onChangeText:
(12)效果圖
.