一、flux的缺陷
因為dispatcher和Store可以有多個互相管理起來特別麻煩
二、什么是redux
其實redux就是Flux的一種進階實現。它是一個應用數據流框架,主要作用應用狀態的管理
設計思想:
(1)、web應用就是一個狀態機,視圖和狀態一一對應
(2)、所有的狀態保存在一個對象里面
三大原則:
(1)、單一數據源
整個store被儲存在一個Object tree(對象樹)中,並且這個Object tree只存在於唯一一個store中
(2)、state是只讀的
唯一改變state的方法就是觸發action,action是一個用於描述已發生事件的普通對象
(3)、使用純函數來修改(reducer)
為了描述action如何改變state tree,你需要編寫reducers
三、redux適用的場景
(1)、用戶的使用方式復雜
(2)、不同身份的用戶有不同的使用方式(比如普通用戶和管理員)
(3)、多個用戶之間可以協作
(4)、與服務器大量交互,或者使用了WebSocket
(5)、View要從多個來源獲取數據
當項目多交互、多數據源的時候必須用到redux
從組件的角度來看什么時候用到redux
(1)、某個組件的狀態,需要共享
(2)、某個狀態需要在任何地方都可以拿到
(3)、一個組件需要改變全局狀態
(4)、一個組件需要改變另一個組件的狀態
四、redux的工作流程
如果我們有一個組件,那么想要獲取數據就需要從Store中獲取數據,當組件需要改變Store數據的時候。需要創建一個Action,然后通過 dispatch(action) 傳遞給Store,然后Store把Action轉發給Reducers. Reducers會拿到previousState(以前的state數據) 和action。然后將previousState和action進行結合做新的數據(store)修改。然后生成一個新的數據傳遞給Store 。Store發送改變那么View也會發生改變
五、創建Store
在Flux中Store是我們手動創建的,但是在redux中Store是redux提供的
(1)、安裝 yarn add redux --dev
(2)、引入 import { createStore } from "redux";
(3)、創建一個store = createStore(reducer)
這樣創建一個store我們沒有辦法進行存值,因此我們需要在createState中傳遞一個參數reducer這個參數就相當於Flux中的dispatcher遺留產物。這個遺留產物有一個規范就是內部必須是一個純函數
(4)、創建reducer.js
這個函數里面有2個參數一個是state,另一個是action。
state指的是store中的數據
action指的是View修改數據的時候傳遞過來的action
這個函數必須返回一個新的數據,而且還不能對老的數據進行修改(Reducer函數中不能改變state,必須返回一個全新的對象)
我們可以先把這個state設置一個默認值defaultState。在defaultState這個對象中我們可以定義一些初始的數據
官方解釋reducer:
Reducer 只是一些純函數,它接收先前的 state 和 action,並返回新的 state。剛開始你可以只有一個 reducer,隨着應用變大,你可以把它拆成多個小的 reducers,分別獨立地操作 state tree 的不同部分,因為 reducer 只是函數,你可以控制它們被調用的順序,傳入附加數據,甚至編寫可復用的 reducer 來處理一些通用任務,如分頁器
(5)、導出Store
導出的store這個對象中默認自帶了一些方法
(1)、dispatch:用來傳遞action
(2)、getState:返回值就相當於this.state中的數據,里面存放着公共的數據
(3)、replaceReducer:
(4)、subscribe:監聽數據的改變,必須傳遞一個函數
(5)、Symbol(observable):
六、創建Action
七、將Action傳遞給store
方法:store.dispatch(action)
當調用完這個方法后action會自動傳遞給reducer,這也是我們為什么在reducer中定義參數action 的原因。在reducer中我們會對action中的type進行比較,如果比較成功則返回一個新的state
八、監聽數據的改變
store.subscribe()
九、如何將reducer拆分成多個reducers
(1)、引入combineReducers
import { combineReducers, createStore } from "redux";
(2)、合並多個reducers
let reducer = combineReducers({ todoReducers, tabReducers })
(3)、創建store
let store = createStore(reducer)
栗子:
注意:在使用state的時候要注意使用的誰的state
十、純函數的概念
同樣的輸入必須得到同樣的輸出
約束:
不得修改參數
不能調用系統I/O的API
不能調用Date.now()或者Math.random()等不純的方法,因為每次得到值是不一樣的結果
十一、redux與flux的區別
Redux沒有Dispatcher,且不支持多個store,Redux只有一個單一的store和一個根級的reducer函數。隨着應有的不斷變大,根級的reducer要拆分成多個小的reducers,分別獨立的操作state的不同部分,而不是添加新的 stores。這就像一個 React 應用只有一個根級的組件,這個根組件又由很多小組件構成