誰都能聽懂的Redux+Redux-Saga超級傻瓜教程


對不起本文確實有標題黨的嫌疑:) 想要理解本文還是要先會用reactes6,如果連reactes6都不知道是什么的話我也沒轍:(

 

如果你選擇用react來開發應用,並且你沒對各個組件的狀態進行應有的管理,那么當應用變得龐大的時候你會發現組件之間的通信變得錯綜復雜,各個組件之間的數據傳遞往往會亂成一團,從而導致加班、延期、炒魷魚等不好的事情:( 這個時候就需要引入“狀態管理”這個概念來挽救一團亂麻的代碼。狀態管理,就是將各個組件之間相互獨立的狀態和數據給統一的管控起來,讓原本錯綜復雜的數據流向變成單向,這樣狀態就變得容易管理和理解,從而讓程序變得易於維護。

 

今天我們講的就是react目前最流行的狀態管理工具redux和它的一些周邊組件。廢話不多說,我們先准備好react開發環境,打開ide開始敲代碼。

 

環境這塊我就不講了,最基礎的webpack+react即可。

首先先安裝reduxyarn add redux -S),清空src目錄,新建一個入口js文件(index.js),輸入以下內容:

 

import { createStore } from 'redux'

const reducer = function (state, action) {
  console.log(action.type)
  return state
}

const store = createStore(reducer)

store.dispatch({type: 'hello'})

 

 

 

然后啟動dev server,打開瀏覽器和控制台,就可以看到輸出了“hello”。現在來稍微解釋下這段代碼:

createStore,從字面上理解,就是創建倉儲,這個倉儲用來存放數據和修改數據的方法。

 

dispatch,直譯過來是指派、調度,可以理解成命令store執行修改數據的操作。傳入一個對象來描述要執行的動作。我們稱這個對象為action

 

reducer,直譯過來是還原劑,這里就把它理解成存放數據和修改數據的方法的地方。如果把store比喻成倉庫,那么reducer就是用來裝載貨物的集裝箱。reducer接受的第一個參數是數據,第二個參數用來描述動作,里面是dispatch過來的對象和數據,我們可以利用type屬性結合switch case語句來進行具體的狀態修改。還有要記得返回state,如果沒有返回state就會報錯。

 

我們把reducer扔到createStore這個函數里,就返回了一個store。然后再調一下store里面的dispatch方法,就執行了一次reducer。這樣一個最簡單的redux管理狀態的流程就跑完了。

在這個例子里我們只使用了一個reducer,而一個reducer只有一個state,但是我們的應用肯定不止一個組件,這個時候就需要多個reducer

為了將多個reducer組合起來,我們又要引入一個redux里的函數,叫combineReducers

import {combineReducers, createStore} from 'redux'

const list = function (state = [], action) {  //state=[]表示的是state的初始狀態
  console.log(action.type)
  console.log('list')
  return state
}

const counter = function (state = 0, action) {
  console.log(action.type)
  console.log('counter')
  return state
}

const reducers = combineReducers({
  list, counter
})

const store = createStore(reducers)

store.dispatch({type: 'hello'})

 

 

這樣就將多個reducer組合起來了。調用dispatch的時候所有reducer都會被執行。

 

 

到了這里我們就已經可以進行一些簡單的本地狀態管理了。但是幾乎所有的應用都有涉及到ajax異步請求,這些代碼要放到哪里呢?如果放到reducer里的話由於reducer要求立即返回state,不然報錯。解決方案是有的,不過有些繁瑣,可以參考阮一峰老師的教程:

http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html

如果沒看懂的話也沒關系,如果你能夠在項目中運用redux-saga的話,就可以很輕松的解決異步問題了:)

我們先認真的把redux-saga官方提供的案例給看一看

https://redux-saga-in-chinese.js.org/docs/introduction/BeginnerTutorial.html

redux-saga的使用很簡單,和之前redux的做法差不多。先定義saga(也稱為effect。類似reducer,不過可以調用異步方法,不能修改狀態),然后在頂層(index.js)注冊之前寫好的saga即可。

sagaeffect)中,我們可以通過takeEvery來監聽dispatch,通過call來調用異步方法,通過put來觸發reducer,通過select來獲取狀態。要注意的是saga都是Generator函數(帶*號),也只有Generator函數里才能調用yield。這樣異步問題就差不多解決了。

 

說了這么多,總得應用到react里面去吧。react里的各個組件想要獲取到store里的狀態和命令store進行數據修改,如果不安裝其他包的話就只能在根級組件把store一級一級的傳遞下去,中間有一級沒傳遞store那么之后的組件就全部無法使用redux進行狀態管理了,這樣顯然是有待改進的。所以我們還要再裝一個包:react-redux

React-redux核心的方法只有兩個:ProviderconnectProvider用來包裹根級組件,並接收storeconnect用來將組件的propsstore連接起來,這樣即使不一層層的傳遞store每個組件也可以接收到store

export default connect((state) => {
  return {list: state.userList.list} // 將store與組件連接起來。connect第一個參數是一個函數,要求返回用來描述props和store的對象。
})(List) 

 

 

這樣我們基本上就能把redux給實際的應用起來了,但是還有一個問題值得我們思考:store調用dispatch后所有的reducer都會被執行,而每個reducer里面只能用switch case之類的流程控制語句來指定執行哪個reducer,如果項目一大,各個方法的命名豈不是很容易混亂?別着急,這個時候需要本文要談到的最后一個包:dvajsdvajs將一組數據和相應的修改數據的方法包裝成一個module,組件調用dispatch的時候可以通過指定type屬性來直接調用相應moduleeffect或者reducerdvajs的具體使用除了參考官網的案例以外,還可以參照這篇博文:https://www.cnblogs.com/axel10/p/8503782.html。只要你能夠從redux->redux-saga->react-redux這個流程學下來,就會發現dvajs幾乎沒有多少新知識點,很快就能夠上手。

如果覺得教程里有地方講的不是很理解的可以將下面這個案例下載下來看一看,相信很多問題都會得到答案。

一個在線獲取用戶列表,點擊項目可刪除的例子

https://github.com/axel10/react-redux-redux-saga-example


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM