Redux學習筆記(一)
Redux 是 JavaScript 狀態容器,提供可預測化的狀態管理。
使用Redux應該遵循一下原則:
- 整個應用共享的state應該存儲在store的狀態樹中,store是唯一的;
- state不能直接修改,只能通過action表達修改的意圖,調用dispatch()修改state;
- state的修改規則reducers必須是一個純函數,不能有副作用。
Redux提供的API
createStore
createStore方法的作用就是創建一個 Redux store 來以存放應用中所有的 state。
createStore(reducer, [preloadedState], [enhancer])
createStore方法接受三個參數 ,後面兩個是可選參數:
reducer :參數的類型必須是 function。
preloadedState : 這個參數代表初始化的state(initState),可以是任意類型的參數。
enhancer : 這個參數代表添加的各種中間件,參數的類型必須是function。
中間的preloadedState參數可以直接省略不寫,redux已經對這種情況做了處理:
/* *如果第二參數preloadedState 是function,且第三個參數enhancer 省略, *把第二個參數賦值給enhancer */ if (typeof preloadedState === ‘function‘ && typeofenhancer === ‘undefined‘) { enhancer = preloadedState preloadedState = undefined }
createStore提供的方法:
getState() :
返回當前的state,利用閉包獲得currentState。
subscribe(listener) :
訂閱事件,傳入的參數listener必須是一個函數。主要作用是當state發生改變的時候,能夠得到通知,通過subscribe,傳入的監聽函數在dispatch函數中會全 部執行一次。
返回值是一個函數,執行返回的函數會從listeners中移除當前的listener。這裏也是利用了閉包。
function subscribe(listener) {
//判斷listenner是不是一個函數 if (typeof listener !== ‘function‘) { throw new Error(‘Expected listener to be a function.‘) } //定義這個變量是防止已經從listeners中移除的listener再次取消訂閱 let isSubscribed = true ensureCanMutateNextListeners() nextListeners.push(listener) //利用閉包,取消訂閱 return function unsubscribe() { if (!isSubscribed) { return } if (isDispatching) { throw new Error( ‘You may not unsubscribe from a store listener while the reducer is executing. ‘ + ‘See http://redux.js.org/docs/api/Store.html#subscribe for more details.‘ ) } isSubscribed = false ensureCanMutateNextListeners() const index = nextListeners.indexOf(listener) nextListeners.splice(index, 1) } }
dispatch(action) :
參數action必須是一個對象,且必須含有type字段;
作用:執行reducer,修改store裏面的數據;執行訂閱函數。
function dispatch(action) {
//檢查傳入的action是不是一個對象 if (!isPlainObject(action)) { throw new Error( ‘Actions must be plain objects. ‘ + ‘Use custom middleware for async actions.‘ ) } //檢查傳入action是否有type字段 if (typeof action.type === ‘undefined‘) { throw new Error( ‘Actions may not have an undefined "type" property. ‘ + ‘Have you misspelled a constant?‘ ) } if (isDispatching) { throw new Error(‘Reducers may not dispatch actions.‘) } //執行reducer try { isDispatching = true currentState = currentReducer(currentState, action) } finally { isDispatching = false } //執行訂閱函數 const listeners = (currentListeners = nextListeners) for (let i = 0; i < listeners.length; i++) { const listener = listeners[i] listener() } return action }
replaceReducer(nextReducer) :
動態的替換當前的reducer
function replaceReducer(nextReducer) { if (typeof nextReducer !== ‘function‘) { throw new Error(‘Expected the nextReducer to be a function.‘) } currentReducer = nextReducer dispatch({ type: ActionTypes.REPLACE }) }
observable():
這個方法查閱其他資料解釋的是配合其他特點的框架或編程思想來使用的,如rx.js,一般用不到
這個方法我也不太懂 - -#,官方推薦的學習渠道 https://github.com/tc39/proposal-observable
function observable() { const outerSubscribe = subscribe return { subscribe(observer) { if (typeof observer !== ‘object‘) { throw new TypeError(‘Expected the observer to be an object.‘) } function observeState() { if (observer.next) { observer.next(getState()) } } observeState() const unsubscribe = outerSubscribe(observeState) return { unsubscribe } }, [$$observable]() { return this } } }
createStore總共暴露了五個API:
- dispatch
- subscribe
- getState
- replaceReducer
- [$$observable]: observable
前三個是常用的API
Redux學習筆記(一)