Redux是javascript的狀態容器,它提供了可預測的狀態管理。注意Redux和React並沒有特別的聯繫,你不管使用什麼框架,Redux都可以作爲一個狀態管理器應用到這些框架上。
Redux的三大定律:
- 單一數據源
- state是隻讀的
- 使用純函數執行修改
解釋一下這三大定律,首先是單一數據源,整個應用的state都儲存在一個javascript對象中,Redux用一個store對象來儲存整個state,我們可以把這個store對象理解成一個全局變量,整個應用中只有一個store對象。
第二state是隻讀的,那個要想改變state,就只能通過store對象,store對象有一個方法叫做dispatch,dispatch有個參數叫做action,我們可以把這個action理解爲一個裝載信息載體的普通的javascript對象,最後要改變state,只需調用store.dispatch(acation)即可。
第三使用純函數執行修改,那麼我們有了一個action,執行了store.dispatch(action),比如action是一個刪除文章的信息載體,那麼我們執行了store.dispatch(acation)之後,state是怎麼變化呢,就需要一個純函數來執行對state的修改。在Redux中,我們稱這個純函數爲reducer,既然reducer是一個函數,那麼就會有參數和返回值,這裏reducer的參數爲先前的state和要處理的action,返回值爲一個新的state。
Redux的組成
在說Redux的三大定律的時候已經涉及到Redux的組成,Redux有三部分組成,分別是action、reducer和store,下面再一一解釋:
action:
剛纔說到action其實就是一個裝載信息載體的javascript對象,比如說可能爲一個刪除文章的信息載體,那麼這麼一個action需要裝載什麼信息呢?首先需要一個唯一的標示,來告訴大家這個action就是用來刪除文章的,然後還需要一個文章ID,來說明要刪除哪一篇文章。然後用代碼的形式展現出來就是:
const DELETE_ARTICLE = 'DELETE_ARTICLE';
function deleteArticle(id){
return {
type:DELETE_ARTICLE,
id:id
}
}
這就是一個標準的action。
reducer:
我們剛纔說reducer是一個純函數,它的作用就是生成一個新的state,這個函數有兩個參數,一個是以前的state,另一個是要執行的action,最後通過函數中的一些表達式邏輯判斷,生成一個新的state,這裏需要注意的是生成一個新的state,而不是在原來的state上改造。
例如:
let initState = [
{'id':1,'title':'文章一'},
{'id':2,'title':'文章二'},
{'id':3,'title':'文章三'}
]
function deleteArticleReducer(state = initState,action){
switch(action.type){
case 'DELETE_ARTICLE':
return state.filter((article) => {
return article.id != action.id;
});
default:
return initState;
}
}
store:
在說Redux的三大定律的時候,store已經多次提到,那麼store就是action和reducer的黏合劑,在action和reducer中我們發現並沒有Redux的代碼,那麼怎麼生成一個store呢?如下:
import {createStore} from 'redux';
import reducer from './reducer';
let store = createStore(reducer)
生成一個store需要用到Redux庫中的createStore函數,函數有一個參數,就是reducer,那麼我們拿到store可以做什麼操作呢:
- 保存整個程序的state
- 通過getState()方法訪問state的值
- 通過dispatch()方法執行一個action
- 通過subscribe(listener)註冊回調,監聽state的變化
數據流
剛纔用刪除文章舉例說明了Redux,那麼整個數據流可以分爲一下幾步:
- 調用store.dispatch(action)來執行刪除文章的操作
- store對象中存在所有的reducer函數(因爲store = createStore(reducer);),那麼當前的state和action會根據action中的type(唯一標示)執行對應的reducer
- reducer執行完之後會返回一個新的state
- store保存reducer返回的state,然後可以通過store.getState()獲取。