redux狀態管理器,實質上就是一個單例模式。咱們來實現一個簡單的redux模型,實現以前咱們要先熟悉它的用法。 redux
下面咱們按照這個思想來想一想怎麼作。 咱們來抽象一下,提取出最核心的思想,動用鬼斧神工畫個圖:數組
用文字來描述一下,一個惟一的倉庫裏,有一個私有屬性state,倉庫由門衛大哥進行管理,全部對state的操做都要通過門衛大哥,外面的人無權直接對state進行操做,若是有進行訂閱,則在狀態改變後收到狀態改變事件。好了,咱們按照這個思想來開始code吧函數
const state={ a: 1 }
function createStore(){ const state={ a: 1 } }
function createStore() { let state={ a:1 }; function getState() { return state //此處直接將state返回,會使state引用地址暴露,從而被引用對象改變值 } return { getState } } let store = createStore() // 建立一個倉庫 let state = store.getState() // 獲取狀態state console.log(store.getState()) // 輸出{ a: 1 } state.a = 2 //將state a的值設置爲2 console.log(state) // 輸出爲{ a: 2 } console.log(store.getState()) // 此時倉庫中state的值也改變了,輸出爲{ a: 2 }
因此咱們將第六行 return state
替換爲 return JSON.parse(JSON.stringify(state))
能夠避免這個問題。優化
'use strict' function createStore() { let state; function getState() { return JSON.parse(JSON.stringify(state)) } function dispatch(action) { // 分發 state = reducer(state,action) // 接收當前 State 和Action做爲參數,返回一個新的 State } dispatch({ type: '@@INIT' }) // 在建立倉庫的時候,初始化state的值 return { getState, dispatch } } let initState = { count: 0 } //處理器,接收二個參數 ,接收老狀態和action,返回新狀態 function reducer(state = initState, action) { // 若是state沒有值,默認值爲initState //判斷動做的類型 switch (action.type) { case 'ADD_TODO': return { ...state, count: action.number }; //...state解構state全部屬性,count: action.number覆蓋前面的值 default: return state; } } let store = createStore() // 建立一個倉庫 let state = store.getState() // 獲取狀態state let action = { type: 'ADD_TODO', number: 1 }; store.dispatch(action); // 派發一個action,改變state的狀態 console.log(store.getState()) // 輸出{ count: 1 }
diapatch中執行咱們定義的reducer處理器函數,增刪改查。例子演示了先建立一個倉庫,在建立新倉庫的時候初始化了state。而後diapatch一個action:ADD_TODO,執行的處理是改變count的值,返回一個新的state對象,最後咱們能夠看到輸出,原來的state在初始化後變成{ count: 0 },又在ADD_TODO後變成了{ count: 1 }。spa
reducer函數是咱們在使用redux時須要本身定義的處理函數。code
至此,咱們已經實現了建立一個倉庫,而且能夠自定義一些處理函數對state進行操做。還缺了什麼呢?在實際項目中,狀態改變後咱們的大部分的組件須要當即獲得新的狀態,而後根據狀態改變做出不一樣的處理。也就是說組件對state進行一個監聽,一旦state發生改變,立馬通知到對應的組件。讓咱們來繼續實現吧。。。cdn
function createStore() {
let state;
let listeners = [];
function getState() {
return JSON.parse(JSON.stringify(state))
}
function dispatch(action) { // 分發
state = reducer(state,action); // 接收當前 State 和Action做爲參數,返回一個新的 State
listeners.forEach(listener => listener()) // 一旦狀態改變,觸發全部的監聽函數,這裏須要優化,只有相關狀態改變才須要觸發
}
function subscribe(listener){ // 訂閱,若是需監聽狀態變化,將監聽函數傳過來
listeners.push(listener); // 保存監聽函數到監聽數組
return function () { // 返回取消訂閱的函數
listeners = listeners.filter(item => item != listener); // 過濾監聽函數
}
}
dispatch({ type: '@@INIT' }); // 在建立倉庫的時候,初始化state的值
return {
getState,
dispatch,
subscribe
}
}
/*這裏是分割線,上面一部分是倉庫定義,下面部分是使用方法*/
let initState = {
count: 0
}
//處理器,接收二個參數 ,接收老狀態和action,返回新狀態
function reducer(state = initState, action) { // 若是state沒有值,默認值爲initState
//判斷動做的類型
switch (action.type) {
case 'ADD_TODO':
return { ...state, count: action.number }; //...state解構state全部屬性,count: action.number覆蓋前面的值
default:
return state;
}
}
let store = createStore() // 建立一個倉庫
let action = { // 定義一個action
type: 'ADD_TODO',
number: 1
};
let unADD = store.subscribe(function(){ // 監聽狀態改變
console.log('狀態改變了,如今的state爲:') // 狀態改變了,如今的state爲:
console.log(store.getState()) // { count: 1 }
})
store.dispatch(action); // 派發一個action,改變state的狀態
複製代碼
鐺鐺鐺~,咱們的redux基本模型就作好了,有什麼不懂的能夠提問喲~對象