Redux-学习笔记
文章目錄
- Redux-學習筆記
- 安裝Redux
- Redux簡介(為什么要用Redux?)
- Redux和React
- React-redux
- redux-actions使用
- 項目打包
Redux-學習筆記
安裝Redux
redux需要安裝以下依賴:
cnpm install redux --save cnpm install react-redux --save cnpm install redux-actions --save@connect裝飾器報錯處理
因為用到了es6/7的語法,需要安裝babel轉碼
在package.json中添加插件支持ES7:
Redux簡介(為什么要用Redux?)
先來看看React里面的數據是怎樣傳遞的(下圖中并不是說this.state只能在“團長”處,這里只是為了簡便,所以才這樣寫,其實營長,連長都可以有自己的this.state):
React數據流:
這個過程是不能越級的,比如說你一連長發現了敵情就不能直接報告團長,而必須先報告給一營長,一營長再報告給團長,這里層級還不是特別深,你再來個排長,班長什么的,按照這種模式,等團長知道敵情,敵人都打到家門口啦,又或者說一連長想找三連長喝個酒,還得先把這個消息傳給營長,再傳給團長,再傳給二營長再傳給三連長,這……
Redux橫空出世
所以說層級不深,組價之間也沒有什么公用數據的時候,用React自身的setState其實也可以了,可是嵌套一深,或者組件有一些公用數據時就比較麻煩了,于是就有了redux(其實之前還有個flux),回到這個例子就是,他們在整個團之外又建立了一個通訊班(Redux):
看起來就像下面這樣:
這里只是一個很簡單的示意圖,實際使用并非如此,這個圖示為了讓大家理解React中的數據和Redux中的數據是獨立的,并沒有任何關系。
Redux
現在讓我們拋開戰斗編制(React),單看通訊班(Redux)。
其實網上講Redux的教程非常多,這里就簡單說一下:
store
store:首先要創建一個對象store,這個對象有各種方法,用來讓外界獲取Redux的數據(store.getState),或者讓外界來修改Redux中的數據(store.dispatch)
action:描述我要干啥,一般是一個對象的形式,其中有一個type字段是必須要有的,比如:{ type:‘請求增援’ },還可以帶點數據{ type:‘請求增援’,gun:"100" }
reducer
reducer:擼開袖子真刀實槍的就去干了,比如一連長要求增援,增援要求是100桿槍,團長馬上就給你加了100桿槍送了過去。
action和reducer也可以想象成產品經理和程序員的關系。
產品經理:“我要一個按鈕,圓角的”
程序員:“嗯,做好了”
產品經理:“換個顏色吧,紅色”
程序員:“ok,換好了”
差不多就是這樣,產品經理并不操心具體怎么實現的,他只說他想要干什么(type),然后再提點實現的要求(各種其他的數據),程序員就去具體實現(reducer,修改state,然后返回一個全新的state,這里注意我們并沒有直接返回原來的state,我們返回的是一個全新的state對象,因為reducer函數是一個沒有副作用的純函數)
那怎么去觸發這個操作(action)呢,就好比說我一連長發現敵情了,我怎么報告給通訊班,讓通訊班來處理呢?
就是上面提到過的store.dispatch,不過還要加一個參數,那就是action
store.dispatch({ type:‘請求增援’,gun:"100" })這樣就可以觸發action,執行reducer,得到一個全新的state。
小例子:
Redux和React
到此為止,Redux自己就折騰完了,那么Redux自己的數據并沒有用,它要把數據交給React用才行,接下來講一講怎么把數據交給React來用。
上面我們創建了一個對象store,我們要把這個store對象作為props傳給React,那React就可以用了。
這個store只能有一個,也就只能創建一次,也就是說你必須在最頂層處創建一個store對象,然后再一層層的傳遞下去,才能讓所有的組件都能獲得這個store對象,調用它的方法。
獲取Redux中的數據
比如說我要在render函數中顯示Redux的數據,那么我就可以先獲取它的數據:
然后把這個數據當做props渲染到組件中去就行了。
更新Redux中的數據
如果你要修改它的數據,那就在JSX中調用
響應Redux中的變化
那么這里問題又來了,你調用了store.dispatch之后Redux中的數據確實改變了,可是React并沒有什么變化啊。也就是說React中的render函數并沒有被觸發呀是不是,就好像React中你直接修改React中的state是沒有用的而必須調用React的setState才能重新渲染。
因此,為了讓Redux的數據一改變我們就重新渲染,Redux自己提供了一個方法叫做
這個函數可以監聽Redux中state的變化,一旦Redux中的state發生了變化,render函數就會被調用,頁面就會被重新渲染。
上面這個過程就是手動調用的過程,但這樣調用有點麻煩,因為要讓所有的子組件都能應用store中的數據,那么所有的組件就都要把store當做props傳進來,這也太麻煩了。
還是那之前那個例子來說,你一連長發現了敵情,是不用層層上報了,可以直接報告給通訊班,通訊班再生成新的命令,可問題是,你從下往上打報告是簡單了,可是從上往下發布命令仍然是一層層的傳遞的呀。
就好比說,一連長發現了敵情,報告上去,通訊班做出決定讓三連長帶人去打,通訊班還是得通過團長–營長–連長這條路去一層層發布命令,能不能讓通訊班直接就通知三連長呢,當然是有的,這就是我們的React-redux庫
React-redux
這個是需要你自己去用npm額外安裝的。
使用這個方法之后,我們就不需要一層層往下發布命令了
在React-redux中有兩個比較關鍵的概念:Provider和connect方法。
一般我們都將頂層組件包裹在Provider組件之中,這樣的話,所有組件就都可以在react-redux的控制之下了,但是store必須作為參數放到Provider組件中去
這個組件的目的是讓所有組件都能夠訪問到Redux中的數據。
redux-actions使用
redux-actions有兩大法寶createAction和handleActions
createAction
原來創建action:
使用redux-actions創建action:
import { createAction } from 'redux-actions'; const startAction = createAction(START);handleActions
原來reducer操作state寫法要使用switch或if else來匹配:
使用redux-actions``reducer操作state:
const timer = handleActions({START: (state, action) => ({ ...state, runStatus: true }),STOP: (state, action) => ({ ...state, runStatus: false }),RESET: (state, action) => ({ ...state, seconds: 0 }),RUN_TIMER: (state, action) => ({ ...state, seconds: state.seconds + 1 }), }, defaultState);項目打包
npm run build
打包成功后,新增build文件
如何訪問?
輸入npm install -g serve 或者 cnpm install -g serve 安裝服務,或者使用nginx,可見https://blog.csdn.net/hhhmonkey/article/details/119333875類似
進入build目錄輸入 serve
在瀏覽器輸入 http://localhost:5000
總結
以上是生活随笔為你收集整理的Redux-学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: React学习:路由定义及传参、数据复用
- 下一篇: 实现一个简单的模板引擎,输入模板和数据,