首先丟擲一個問題。Redux是什麼?
百度百科給出的解釋是:
Redux對於JavaScript應用而言是一個可預測狀態的容器。換言之,它是一個應用資料流框架,而不是傳統的像underscore.js或者AngularJs那樣的庫或者框架。
Redux官方給出的解釋是
Redux 是 JavaScript 狀態容器,提供可預測化的狀態管理。可以讓你構建一致化的應用,執行於不同的環境(客戶端、伺服器、原生應用),並且易於測試。不僅於此,它還提供 超爽的開發體驗,比如有一個時間旅行偵錯程式可以編輯後實時預覽。
其實說的再多,最後還是一句話,就是負責將狀態變得可控。
那麼什麼是狀態呢,在React中State就是用來儲存狀態,而狀態就是一些資料狀態和配置引數。每個元件都可以擁有自己的狀態,而這些變數的值會因為一些操作而改變,而這些改變又會引起其他元件的改變,而state已經不知道什麼時候就脫離了你的控制,而Redux的出現拯救了萬千前端工程師於狀態迷失的水火之中。
阮一峰老師在介紹Redux時提到:
Redux 是一個有用的架構,但不是非用不可。事實上,大多數情況,你可以不用它,只用 React 就夠了。
曾經有人說過這樣一句話。
"如果你不知道是否需要 Redux,那就是不需要它。"
Redux 的創造者 Dan Abramov 又補充了一句。
"只有遇到 React 實在解決不了的問題,你才需要 Redux 。"
雖然說了那麼多但是我們這篇文章的內容呢,是要捋清Redux中的內容,不能跑題啊!
下面開始介紹Redux
1.Redux三大原則
(1).單一資料來源
官方解釋:整個應用的 state 被儲存在一棵 object tree 中,並且這個 object tree 只存在於唯一一個 store 中。 為了避免狀態的混亂,所以在Redux中規定了整個應用的state只存在一棵物件樹中,而這棵樹只能存在一個Store中。對開發者來說,這樣可以更加容易對資料進行除錯,並且可以觀察到資料的詳細變化,在 樹狀結構中,也可以輕鬆實現“撤銷/重做等以前不宜實現的功能
(2).State是隻讀的
官方解釋:唯一改變 state 的方法就是觸發 action,action 是一個用於描述已發生事件的普通物件。 State是不能直接修改的,於React中的state和setState類似,如果需要修改State中的內容,需要先寫一個action物件,通過呼叫這個action來表明你想要State中的內容進行修改的意圖。並且State是不能夠修改的,所以修改的實質是返回一個全新的State。
(3).使用純函式來執行修改
官方解釋:為了描述 action 如何改變 state tree ,你需要編寫 reducers。 Reducers負責根據你給他的action來對State進行操作。Reducers是一個純函式,也就是一個不會產生副作用的函式,因此他最終返回的,是原來的狀態,加上操作的內容產生的新的物件。
2.Redux實現的鋪墊
Redux的實現可以講成一個故事,在一個用玻璃牆圍起來屋子裡面有一個展示牌--State,所有人都可以看見,但是不能夠直接修改展示牌上面的資訊,但是不能修改也不行啊,於是找來了一個專門修改展示牌內容的工匠--reducer,只有他可以修改展示牌上面的State內容,但是State是隻讀的,所以每一次修改都需要工匠重新做一塊牌子,將修改資訊和原來資訊刻在上面,然後展示出來。工匠是住在玻璃牆裡面的,外面的人需要修改展示牌內容,但是沒有辦法進到牆裡面去,所以修改意見沒有辦法傳遞給工匠。於是就產生了一個可以穿過玻璃牆和工匠傳信的信使--action,他可以穿過玻璃牆,傳遞資訊,外面想要修改展示內容的人,只需要將修改意見的暗號--type告訴信使,他便可以告訴工匠,工匠也就按照暗號將資訊修改。故事講完了,下面講講裡面的知識點吧!
(1).展示牌--State:
在Redux第一,二條原則中說到,State儲存在Object tree中,所以在Redux中,所有的State都被儲存在一個單一的物件中,State是隻讀的,所以需要用const來宣告
//定義State
const initState={
todos:[
{content:"HTML",complete:false},
{content:"CSS",complete:true},
{content:"JS",complete:false}
],
visibility:"all"
}
複製程式碼
(2).信使--action:
action是一個物件,用來表明想要對State進行的操作。因為State被隔離了起來,所以想要操作State怎麼辦呢?只好找了一個信使-action,將想要進行的操作告訴信使,由他把操作傳遞給工匠reducer。action的結構比較簡單,分為下面兩個部分。
a.必需品
信使的作用就是傳信,而這裡的信就是type,所以,每個action必須有type的屬性,並且是唯一的。
const decrement = {
type:"DECREMENT"
}
複製程式碼
b.高階操作--action creators
初級信使只傳遞一個修改的type,而修改的方法是工匠已經規定好的,但是這樣的規定往往不能滿足人們的需求,於是就有了高階信使,他們不再是一個物件,變成了一個方法,他可以接收人們需要增加的其他功能,然後整合成一個初級信使模樣即物件,也就是返回一個物件,而這個物件的功能就比初級的信使要厲害多了。
function addTodo(text){
return{
type:"ADD_TODO",
text
}
}
複製程式碼
(3).工匠--reducer
reducer是一個純函式,接收舊的狀態和action,返回一個新狀態。就行工匠一樣,只需要原本的展示牌的內容和信使傳遞的修改意見,只要他能夠識別暗號,就可以做出一個新的展示牌。
function reducer(state=initState, action){
switch(action.type){
case "INCREMENT":
return {count:state.count+action.step}
case "DECREMENT":
return {count:state.count-1}
default:
return state;
}
}
複製程式碼
但是有時候State tree過於龐大的時候,每一次操作的過程太複雜,這時候就產生了工匠聯盟。
工匠聯盟
所謂的工匠聯盟是指將原本一個工匠的活,根據State內容分成幾個部分,分別交給不同的工匠(reducer)來完成,每一次操作,工匠們只需要完成自己的部分即可,需要修改的進行修改,不需要修改的,將原本的內容復刻上去,產生一個新的展示牌。
//定義 reducer
function todos(state=[],action){
switch(action.type){
case "ADD_TODO":
return [...state,{content:action.text,complete:false}];
case "TAGGLE_TODO":
return state.map(todo=>{
if(todo==action.todo){
return Object.assign({},todo,{complete:!todo.complete})
}
return todo;
})
default:
return state;
}
}
// 定義visibility的reducer
function visibility(state="all",action){
switch(action.type){
case "SET_VISIBILITY":
return action.filter
default:
return state
}
}
const reducer = Redux.combineReducers({
複製程式碼
3.Redux核心--store
Redux的核心是Store,那麼Store是什麼呢,可以說他就是剛才故事裡的那個玻璃屋的管理者,他有三個能力,一個是得到展示欄的內容,一個是訂閱展示牌改變,一個是派發改變展示欄資訊的功能
(1)獲取狀態
雖然我們說是把Store比作了玻璃屋,但是在程式碼世界裡面,沒有所謂的視聽說,所以要想獲得展示牌的內容,就需要使用store提供的第一個能力--store.getState()。通過使用這個方法,就可以拿到展示牌的內容了。
//取值
console.log(store.getState());
複製程式碼
(2)訂閱資訊
雖然使用第一個方法可以拿到展示牌的內容,但是拿到了的資料不會因為State的改變而改變,所以當其他人改變了展示牌上面的State,就需要重新獲取,這無疑是不靠譜的方法,所以這個時候就需要使用Store的第二個能力--store.subscibe()來設定監聽,一旦state發生變化,立即可以執行這個監聽方法內部的函式。
//訂閱
store.subscribe(()=>{
console.log(store.getState());
})
複製程式碼
(3)派發任務
既然能夠獲取資料了,自然是可以改變的,信使進入玻璃牆就是使用的Store的第三個能力--store.dispatch(),在這個方法裡,至少需要傳遞一個引數-action,就好比使用了這個方法,就在玻璃牆上面開啟了一個通道,此時信使就可以通過這個通道,進入到了裡面。
// 通過dispatch派發一個action
store.dispatch(addTodo("redux"));
複製程式碼
通過三步的介紹,相信你已經初步瞭解了Redux的內容,接下來在玻璃牆這裡還有許許多多的內容等待著我們,一步一個腳印的走,我們也一定能夠穿過屬於你的玻璃牆的,讓我們一同加油