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‘ && typeof enhancer === ‘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