上周學習了flux,這周研究了一下redux,其實很早之前都已經在研究他們了,只是之前一直沒搞懂,最近這兩周可能打通了任督二脈,都算入門了。
寫博客的目的主要是做一下筆記,總結一下思路,以及和大家交流交流
在介紹redux之前,先回顧一下上周學習的flux:
flux的流程是:
view觸發action中的方法;
action發送dispatch;
store接收新的數據進行合並,觸發View中綁定在store上的方法; 數據的改變都是來自於store
通過修改局部state,改變局部view。
view-->action-->dispatch-->store-->view
如圖所示:
這里只是大概介紹一下flux。
在介紹 redux之前,自己改版了一個官網的todomvc,讓它只能增加和刪除,因為感覺這樣入門容易一點。
截圖如下:只有新增和單個刪除
代碼在github上: https://github.com/xianyulaodi/reduxTodo
redux的流程是:(截取網上的一張圖)
流程如下:在redux中用戶的操作並不會直接導致view層的更新,而是view層發出actions
通知出發store
里的reducer
從而來更新state
;
state的改變會將更新反饋給我們的view層,從而讓我們的view層發生相應的反應給用戶。
redux中有三個基本概念,Action,Reducer,Store。
Action 作用。
1、用Action來分辨具體的執行動作。比如我是要添加一個項目還是刪除一個項目。
2、操作數據首先得有數據。比如添加數據得有數據,刪除數據得有ID。action就是存這些數據的地方。
3、不帶其他數據,僅僅啟示已有數據需要如何調整,或者需要主動獲取哪些數據。如果我要刪除掉全部數據,只要告知這件事即可
Reducer的作用:
官方描述:Action 只是描述了有事情發生了這一事實,並沒有指明應用如何更新 state。這是 reducer 要做的事情。
這么說吧,Action就像一個指揮者,告訴我們應該做哪些事,比如我要刪除,reducer就會給我們提供‘資源(就是上面說的數據)’,真正的體力勞動者是reducer。
也就是說,action里面的每一種描述,比如新增啦,刪除一個,刪除全部啦,reducer都有一個對應的函數來處理數據。之后返回給你一個新的state
reducer 只是一個模式匹配的東西,真正處理數據的函數,是額外在別的地方寫的,在 reducer 中調用罷了。
Store:
前面兩個,我們知道使用 action 來描述“發生了什么”,和使用 reducers 來根據 action 更新 state 的用法。
Store 就是把它們聯系到一起的對象。Store 有以下職責:
- 維持應用的 state;
- 提供 getState() 方法獲取 state;
- 提供 dispatch(action) 方法更新 state;
- 通過 subscribe(listener) 注冊監聽器
就是說,將action和reducer聯系在一起的是store。
這一點要和flux的store是有區別的,flux的store是數據工廠,所有的數據操作都在store那里執行,而且flux的store可以有多個。
redux中,數據工廠在reducer這里,而不是在store這里。store有且只有一個,切記!!!!
如果你前面學習了flux,再學習redux其實是有一點小困惑的。通過Reducer修改數據給我們帶來了哪些好處?
主要有兩點:
1、數據拆解
2、數據不可變(immutabilit
下面想通過我的那個todomvc分析一下redux的各類結構:
Action:
action/index.js
Actions 是把數據從應用傳到 store 的有效載荷。它是 store 數據的唯一來源。用法是通過 store.dispatch() 把 action 傳到 store。
redux約定 Action 內使用一個字符串類型的 type
字段來表示將要執行的動作。
上面的代碼表明,我要創建兩個動作,一個新增內容,要給我傳回新增的內容,一個是刪除文本,給我傳回一個id過來
reducer
reducers/todo.js
因為對cs6語法不是很熟,所以自己做了一下備注:
因為action只是傳回來一個信號,並沒有說要怎么更新,所以怎么個更新發就交給了reducer,比如如果action傳過來的是ADD_TODO,那么我就將這個文本加進去,並且給它一個最大的id來確定其唯一性。
真正開發項目的時候State會涉及很多功能,在一個Reducer處理所有邏輯會非常混亂,
所以需要拆分成多個小Reducer,每個Reducer只處理它管理的那部分State數據。然后在由一個主rootReducers來專門管理這些小Reducer。
Redux提供了一個方法 combineReducers 專門來管理這些小Reducer。
將多個reducers變為1個,比如我有 todos1,todos2,那么就這樣寫 const rootReducer = combineReducers({todos1,todos2});
reducers/index.js
主要是將多個reducer整合為一個
store
store/configureStore.js
上面章節中,我們使用 action 來描述“發生了什么”,和使用 reducers 來根據 action 更新 state 的用法。
Store 就是把它們聯系到一起的對象。我們這里的作用是,創建了一個Store。createStore 有兩個參數,Reducer 和 initialState。 將reducer的數據更新拿過來,然后如果沒有更新的話就傳一個默認值。
如果有跟新,我們就 replace掉。基本上,所有的數據都在這里了。
稍微再介紹一下Store ,它有以下職責:
維持應用的 state;
提供 getState() 方法獲取 state;
提供 dispatch(action) 方法更新 state;
通過 subscribe(listener) 注冊監聽器。
Store提供了一些方法。讓我們很方便的操作數據。
我們不用關心Reducer和Action是怎么關聯在一起的,Store已經幫我們做了這些事。。
store有四個方法。
getState: 獲取應用當前State。
subscribe:添加一個變化監聽器。
dispatch:分發 action。修改State。
replaceReducer:替換 store 當前用來處理 state 的 reducer。
常用的是dispatch,這是修改State的唯一途徑,使用起來也非常簡單,他看起來是這樣的~ store.dispatch(ADD_TODO),雖然我們這里沒有這樣寫,比如你的view需要有些地方更新數據,就可以這樣來拿數據。
react-redux
這是另一個概念,Redux 是獨立的,它與React沒有任何關系。React-Redux是官方提供的一個庫,用來結合redux和react的模塊。
React-Redux提供了兩個接口Provider、connect。
Provider 是一個React組件,它的作用是保存store給子組件中的connect使用。
connect 會把State和dispatch轉換成props傳遞給子組件。它看起來是下面這樣的:
有點繞,什么意思呢,我的理解是,因為所有的數據都集中在了 store中,Provider從那里把store的數據拿了過來。給它的好朋友 connect,
connect是聯系,連接的意思嘛,所以它將好朋友provider的數據拿了過來,讓它供那些子組件使用。
./index.js
這里就是,provider從store那里拿來了數據,給connect,讓它把這些數據傳給組件。connect怎么沒看到呢,繼續往下看
containers/app.js
app.js這個組件相當於是所有其他組件的父組件,最后一行我們可以看到connect, 將provider從store那里拿來的數據注入給了APP這個組件。
connect 會把State和dispatch轉換成props傳遞給子組件。它看起來是下面這樣的:
它會讓我們傳遞一些參數:mapStateToProps,mapDispatchToProps,mergeProps(可不填)和React組件。
之后這個方法會進行一系列的黑魔法,把state,dispatch轉換成props傳到React組件上,返回給我們使用。
mapStateToProps:
mapStateToProps 是一個普通的函數。 當它被connect調用的時候會為它傳遞一個參數State。 字面意思是,匹配一個state給組件。
mapStateToProps 需要負責的事情就是 返回需要傳遞給子組件的State,返回需要傳遞給子組件的State, 返回需要傳遞給子組件的State,(重要的事情說三遍。。。。)
然后connect會拿到返回的數據寫入到react組件中,然后組件中就可以通過props讀取數據啦~~~~
mapDispatchToProps:
字面意思:匹配dispatch給組件。
與mapStateToProps很像,接收store中的dispatch和props,使頁面可以復寫dispatch方法。我的理解,就是通過mapDispatchToProps這個方法,把actionCreator變成方法賦值到props,每當調用這個方法,就會更新State。有點小頭暈。
慢慢理解吧,確實概念比較多。很容易暈
通過上面的整合,App這個父組件拿到了所有的數據todos,和所有的動作 actions,然后它就可以將這些數據派發給它的所有子組件了。子組件需要什么數據,和操作,來這里來拿即可
最后再粘貼上組件的代碼
components/Header.js
components/TodoTextInput.js
components/TodoItem.js 也就是那個刪除按鈕
components/MainSection.js 也就是列表項
redux算是簡單的入門了,接下來就思考怎么跟項目好好的結合。由於是初學,有誤之處,希望多多包涵,歡迎指出。
react生態系統的學習前路漫漫,react 、 react-router 、 es6 、 redux 、 webpack 、react-native 。 目前不是很懂的是redux和es6和 react-native. 共勉之。 接下來學習一下es6語法,和實戰結合 redux