Redux+ReactRedux源碼解析

export const ActionTypes = {INIT:'@@redux/INIT'}

// 生成一個store,和維護這個store需要的方法

// 維護一個state,暴露dispatch(action)來驅(qū)動調(diào)用傳入的reducer(oldstate,action)得到修改后的state

// 維護一個listener隊列茂缚,在調(diào)用reducer(oldstate,action)后遍歷調(diào)用

// 預(yù)留一個接口增強dispatch的功能(添加中間件)

// 參數(shù):

// reducer? 接受action返回next state tree的一個function

// preloadedState store生成時的初始state

? // 如果通過combineReducers生成了根reducer函數(shù)干像,此時必須使用combineReducers相同的key

// enhancer applyMiddleware 中間件,多個中間件通過appleMiddleware()來組合

// 返回:一個Redux stroe (讀取state,發(fā)送action,監(jiān)聽state改變)

export default function createStroe(reducer,preloadedState,enhancer){

? ? // 入?yún)⒌诙?shù)類型是否為函數(shù)吨娜,第三個參數(shù)未定義

? ? if(typeof preloadedState === 'function' && typeof enhancer == 'undefined'){

? ? // 根據(jù)參數(shù)類型影兽,判斷第二參數(shù)傳入的是enhancer,此時將傳入的值做調(diào)整

? ? ? ? enhancer = preloadedState;

? ? ? ? preloadedState = undefined;? ?

? ? }


? ? if(typeof enhancer !== 'undefined'){

? ? ? ? if(typeof enhancer !== 'function'){

? ? ? ? ? ? throw new Error('enhancer to be a function')

? ? ? ? }

? ? ? ? // 傳入了三個參數(shù),并且第三個參數(shù)is a function(中間件),此時執(zhí)行科里化

? ? ? ? // 先執(zhí)行中間件幅恋,在調(diào)用createStore

? ? ? ? return enhancer(createStroe)(reducer,preloadedState);

? ? }

? ? // 判斷第一個參數(shù)是否是function

? ? if(typeof reducer !== 'function'){

? ? ? ? throw new Error('reducer to be a function');

? ? }

? ? // 參數(shù)校驗成功,傳入了兩個參數(shù)泵肄,且參數(shù)類型也合規(guī)

? ? let currentReducer? = reducer

? ? // 初始state

? ? let currentState = preloadedState

? ? // 構(gòu)造監(jiān)聽隊列

? ? let currentListeners = []

? ? let nextListeners = currentListeners

? ? let isDispatching = false

? ? function ensureCanMutateNextListeners(){

? ? ? ? if(nextListeners == currentListeners){

? ? ? ? ? ? // 淺拷貝監(jiān)聽數(shù)據(jù)

? ? ? ? ? ? nextListeners = currentListeners.slice();

? ? ? ? }

? ? }

? ? // 通過Store去讀state樹

? ? function getState(){

? ? ? ? return currentState

? ? }

? ? // 添加訂閱監(jiān)聽

? ? // 傳入監(jiān)聽回調(diào)

? ? // 返回一個移除監(jiān)聽的方法)

? ? function subscribe(listener){

? ? ? ? if(typeof listener !== 'function'){

? ? ? ? ? ? throw new Error('listent to be a function')

? ? ? ? }

? ? ? ? let isSubscribed = true;

? ? ? ? // 監(jiān)聽前后隊列傳遞

? ? ? ? ensureCanMutateNextListeners();

? ? ? ? // 添加監(jiān)聽

? ? ? ? nextListeners.push(listener)

? ? ? ? return function unsubscribe(){

? ? ? ? ? ? // 是否正在添加監(jiān)聽 同步鎖

? ? ? ? ? ? if(!isSubscribed){

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }

? ? ? ? ? ? isSubscribed = false;

? ? ? ? ? ? // 監(jiān)聽前后隊列傳遞

? ? ? ? ? ? ensureCanMutateNextListeners();

? ? ? ? ? ? // 判斷監(jiān)聽是否已經(jīng)添加到將監(jiān)聽的隊列中

? ? ? ? ? ? const index = nextListeners.indexOf(listener);

? ? ? ? ? ? // 已添加的要移除

? ? ? ? ? ? nextListeners.splice(index,1);

? ? ? ? }


? ? }

? ? //發(fā)送一個Action,驅(qū)動state的改變

? ? // 參數(shù):action,要操作的行為

? ? // 返回:傳入的action

? ? function dispatch(action){

? ? ? ? // 判斷傳入的action是否唯一個原生對象捆交,而不是a Promise, an Observable, a thunk, or something else,

? ? ? ? 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.'

? ? ? ? ? ? );

? ? ? ? }

? ? ? ? // 判斷正在執(zhí)行(同步鎖)

? ? ? ? if(isDispatching){

? ? ? ? ? ? throw new Error('reducers may not dispatch actions');

? ? ? ? }

? ? ? ? // 將當前state,和傳入的action作為參數(shù),調(diào)用reducer獲取修改后的state

? ? ? ? try{

? ? ? ? ? ? isDispatching = true;

? ? ? ? ? ? currentState = currentReducer(currentState,action)

? ? ? ? }finally{

? ? ? ? ? ? isDispatching = false

? ? ? ? }

? ? ? ? // 處理監(jiān)聽

? ? ? ? // 傳遞nextListeners 到currentListeners腐巢,然后執(zhí)行這些監(jiān)聽回調(diào)

? ? ? ? const listeners = currentListeners = nextListeners;

? ? ? ? for(let i = 0;i

? ? ? ? ? ? const listener = listeners[i];

? ? ? ? ? ? listener();

? ? ? ? }

? ? ? ? return action;

? ? }

? ? function replaceReducer(nextReducer){

? ? ? ? if(typeof nextReducer !== 'function'){

? ? ? ? ? ? throw new Error('Expected reducer to be a function')

? ? ? ? }

? ? ? ? currentReducer = nextReducer

? ? ? ? dispatch({type:ActionTypes.INIT});

? ? }

// 為observable/reactive庫預(yù)留的交互接口品追。

? ? 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

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ? // 調(diào)用createStore時,dispatch return initial state

? ? dispatch({type: ActionTypes.INIT})

? ? return{

? ? ? ? dispatch,

? ? ? ? subscribe,

? ? ? ? getState,

? ? ? ? replaceReducer,

? ? ? ? [$$observable]: observable

? ? }

}

// conbineReducers.js reducer組合工具類

// 將一個包含了不同的reducer函數(shù)的對象冯丙,轉(zhuǎn)換成一個集合reducer函數(shù)

// 在集合reducer函數(shù)中調(diào)用每一個子reducer,將他們的結(jié)果肉瓦,聚集到一個state對象中,所用的key要跟redecer

// 參數(shù) 對象(包含多個reducer屬性)

// 返回了一個方法胃惜,遍歷執(zhí)行所有屬性reducer,將每個reducer返回的state,拼裝成一個state樹

// 所以每次dispatch調(diào)用的render時調(diào)用的就是combination()

exprot default function combineReducers(reducers){

? ? // 獲取傳入對象的key集合

? ? const reducerKeys = Object.keys(reducers);

? ? const finalReducers = {};

? ? for(let i = 0;i

? ? ? ? const key = reducerKeys[i];

? ? ? ? // 校驗傳入的對象屬性都有值

? ? ? ? if(process.env.NODE_ENV !== 'production' ){

? ? ? ? ? ? if(typeof reducers[key] === 'undefined'){

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //

? ? ? ? if(typeof reducers[key] === 'function'){

? ? ? ? ? ? finalReducers[key] = reducers[key]

? ? ? ? }

? ? }

? ? // 淺拷貝出有效的reducer屬性

? ? const finalReducerKeys = Object.keys(finalReducers);

? ? let unexpectedKeyCache

? ? if(process.env.NODE_ENV !== 'production'){

? ? ? ? unexpectedKeyCache = {}

? ? }

? ? let shapeAssertingError

? ? try{

? ? ? ? // 調(diào)用finalReducers中每一個reducer的Init事件

? ? ? ? assertReducerShape(finalReducers)

? ? }catch(e){

? ? ? ? shapeAssertingError = e;

? ? }

? ? return function combination(state = {},action){

? ? ? ? if(shapeAssertingError)

? ? ? ? {

? ? ? ? ? ? throw shapeAssertingError;

? ? ? ? }

? ? ? ? if(process.env.NODE_ENV !== 'production'){

? ? ? ? ? ? const warningMessage = getUNexpectedStateShapeWarningMessage(state,finalReducers,action,unexpectedKeyCache)

? ? ? ? ? ? if(warningMessage){

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? let hasChanged = false;

? ? ? ? const nextState = {}

? ? ? ? // 遍歷finalReducers泞莉,構(gòu)建一個state樹,以finalReducers中reducer的key為key,reduer執(zhí)行生成的state為value

? ? ? ? for(let i = 0;i

? ? ? ? ? ? // 獲取reducer的key

? ? ? ? ? ? const key = finalReducerKeys[i];

? ? ? ? ? ? // 獲取reducer的value

? ? ? ? ? ? const reducer = finalReducers[key];

? ? ? ? ? ? // 從state樹上根據(jù)reducer的key獲取之前的state值

? ? ? ? ? ? const previousStateForKey = state[key]

? ? ? ? ? ? // 根據(jù)執(zhí)行reducer的value得到新的state值

? ? ? ? ? ? const nextStateForkey = reducer(previousStateForKey,action);


? ? ? ? ? ? if(typeof nextStateForkey === 'undefined'){

? ? ? ? ? ? ? ? throw new Error();

? ? ? ? ? ? }

? ? ? ? ? ? // 將得到新的state值船殉,update到state樹

? ? ? ? ? ? nextState[key] = nextStateForkey;

? ? ? ? ? ? hasChanged = hasChanged || nextStateForkey !== previousStateForKey


? ? ? ? }

? ? ? ? return hasChanged?nextState:state

? ? }

}

// 中間件集合類

// applyMiddleware,將接受到的middleware參數(shù)裝換成middleware數(shù)組

// 再轉(zhuǎn)換成一個初始參數(shù)為原始dispatch的一元鏈式函數(shù) dispatch = w1(w2(w3(store.dispatch)))

// 從而生成新的加強了的dispatch方法

export default function applyMiddleware(...middleware){

? ? return(createStroe)=>(reducer,preloadedState,enhancer)=>{


? ? ? ? const store = createStroe(reducer,preloadedState,enhancer)

? ? ? ? let dispatch = store.dispatch

? ? ? ? let chain = []

? ? ? ? const middlewareAPI = {

? ? ? ? ? ? getState:store.getState,

? ? ? ? ? ? dispatch:(action) => dispatch(action)

? ? ? ? }

? ? ? ? chain = middlewares.map(middleware => middleware(middlewareAPI))


? ? ? ? dispatch = compose(...chain)(store.dispatch)


//? ? ? dispatch = w1(w2(w3(store.dispatch)))

? ? ? ? return {

? ? ? ? ? ? ...store,

? ? ? ? ? ? dispatch

? ? ? ? }

? ? }

}

// 將第一個函數(shù)調(diào)用結(jié)果做為下一個函數(shù)的參數(shù)

export default function compose(...funcs){

? ? if(funcs.length === 0){

? ? ? ? return arg => arg

? ? }

? ? if(funcs.length === 1){

? ? ? ? return funcs[0]

? ? }

? ? return funcs.reduce(((a,b)=>(...args) => a(b(...args)))

}

// action生成器 bindActionCreator

function bindActionCreator(actionCreator,dispatch){

? ? return (...args) => dispatch(actionCreator(...args))

}

// bindActionCreators

// 將一個所有屬性都是action creators的對象鲫趁,轉(zhuǎn)換成

// 參數(shù):

export default function bindActionCreators(actionCreators,dispatch){

? ? const keys = Object.keys(actionCreators)

? ? const boundActionsCreators = {}

? ? for (let i = 0;i

? ? ? ? const key = keys[i];

? ? ? ? const actionCreator = actionCreators[key]

? ? ? ? if(typeof actionCreator === 'function'){

? ? ? ? ? ? boundActionsCreators[key] = bindActionCreator(actionCreator,dispatch);

? ? ? ? }

? ? }

? ? return boundActionsCreators

}

// React-Redux? redux 在react上應(yīng)用的輔助工具類

// 生成一個控件,使其將createStore生成state作為store ,利用React中的Context屬性

// 對Provider 添加getChildContext和childContextTypes利虫,

// 將store 傳遞到其所有子控件中,以供其訪問

//

// Provider createProvider

//

//? ? Component

//

export function createProvider(storekey = 'store',subKey){

? ? const subscrptionKey = subKey || `${storeKey}Subscription`

? ? class Provider extends Component{

? ? ? ? getChildContext(){

? ? ? ? ? ? return {[storeKey]:this[storeKey],[subscrptionKey]:null}

? ? ? ? }

? ? ? ? constructor(props,context){

? ? ? ? ? ? super(props,context)

? ? ? ? ? ? this[storeKey] = props.store;

? ? ? ? }

? ? ? ? render(){

? ? ? ? ? ? return Children.only(this.props.children)

? ? ? ? }

? ? }

? ? Provider.prototype = {

? ? ? ? store:storeShape.isRequired,

? ? ? ? children:PropTypes.element.isRequired,

? ? }

? ? Provider.childContextTypes = {

? ? ? ? [storeKey]: storeShape.isRequired,

? ? ? ? [subscriptionKey]: subscriptionShape,

? ? }

? ? return Provider

}

//

// export default connect(mapStateToProps, mapDispatchToProps)(containerName)

// 將UI組件(只展現(xiàn)UI)轉(zhuǎn)換成可以訪問Redux API 的容器組件(處理業(yè)務(wù)邏輯挨厚,和管理數(shù)據(jù))

// 通過Provider將createStore生成的state傳遞到其所有子控件后

exprot function createConnect({

//參數(shù)

? ? connectHOC = connectAdvanced,

? ? mapStateToPropsFactories

? ? ...

}={}){

// 函數(shù)體? 返回一個函數(shù)

? ? return function connect(mapStateToProps,mapDispatchToProps,mergeProps

? ? ? ? // 第四個參數(shù)

? ? ? ? {

? ? ? ? ? ? pure = ture,

? ? ? ? ? ? ....

? ? ? ? }

? ? ){


? ? ? ? // 將傳入的mapStateToProps作為實參堡僻,

? ? ? ? // 通過match遍歷調(diào)用mapStateToPropsFactories(數(shù)組)中對應(yīng)的方法(對傳入

? ? ? ? // 的mapStateToProps做判斷校驗)


? ? ? ? ? ? // 如果 mapStateToProps 為null

? ? ? ? ? ? ? ? // wrapMapToPropsConstant(() => ({}))

? ? ? ? ? ? // 如果 mapStateToProps 為function

? ? ? ? ? ? ? ? // wrapMapToPropsFunc(mapStateToProps, 'mapStateToProps')

? ? ? ? ? ? ? ? // export function wrapMapToPropsFunc(mapToProps, methodName) {

? ? ? ? ? ? ? ? ? ? //? ? 返回一個方法

? ? ? ? ? ? ? ? //? ? return function initProxySelector(dispatch, { displayName }) {

? ? ? ? ? ? ? ? ? ? ? ? // 返回一個方法 initProxySelector (initMapStateToProps)

? ? ? ? ? ? ? ? ? ? ? ? // 聲明一個方法 proxy

? ? ? ? ? ? ? ? //? ? ? const proxy = function mapToPropsProxy(stateOrDispatch, ownProps) {

? ? ? ? ? ? ? ? //? ? ? ? ? 調(diào)用proxy 時

? ? ? ? ? ? ? ? //? ? ? ? ? ? ? dependsOnOwnProps?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 為true 執(zhí)行 proxy.mapToProps(stateOrDispatch, ownProps)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 為false 執(zhí)行 proxy.mapToProps(stateOrDispatch)

? ? ? ? ? ? ? ? //? ? ? ? ? return proxy.dependsOnOwnProps

? ? ? ? ? ? ? ? //? ? ? ? ? ? proxy.mapToProps(stateOrDispatch, ownProps)

? ? ? ? ? ? ? ? //? ? ? ? ? : proxy.mapToProps(stateOrDispatch)

? ? ? ? ? ? ? ? //? ? ? }

? ? ? ? ? ? ? ? //? ? ? 給proxy添加屬性 dependsOnOwnProps,標示是否有ownProps參數(shù)

? ? ? ? ? ? ? ? //? ? ? // allow detectFactoryAndVerify to get ownProps

? ? ? ? ? ? ? ? //? ? ? proxy.dependsOnOwnProps = true

? ? ? ? ? ? ? ? ? ? ? ? // 給proxy添加屬性mapToProps

? ? ? ? ? ? ? ? //? ? ? proxy.mapToProps = function detectFactoryAndVerify(stateOrDispatch, ownProps) {

? ? ? ? ? ? ? ? ? ? //? ? 第一次調(diào)用mapToProps時調(diào)用detectFactoryAndVerify,

? ? ? ? ? ? ? ? ? ? //? ? 此時拿到傳入的MapStateToProps 指定給mapToProps

? ? ? ? ? ? ? ? ? ? ? ? ? ? //

? ? ? ? ? ? ? ? //? ? ? ? proxy.mapToProps = mapToProps

? ? ? ? ? ? ? ? ? ? ? ? //? 判斷傳入的 mapToProps 的 dependsOnOwnProps屬性是否為true

? ? ? ? ? ? ? ? //? ? ? ? proxy.dependsOnOwnProps = getDependsOnOwnProps(mapToProps)

? ? ? ? ? ? ? ? ? ? ? ? ? ? //

? ? ? ? ? ? ? ? ? ? ? ? ? ? // 再次調(diào)用proxy疫剃,調(diào)用的就是傳入的 mapStateToProps

? ? ? ? ? ? ? ? //? ? ? ? let props = proxy(stateOrDispatch, ownProps)


? ? ? ? ? ? ? ? //? ? ? ? if (typeof props === 'function') {

? ? ? ? ? ? ? ? //? ? ? ? ? proxy.mapToProps = props

? ? ? ? ? ? ? ? //? ? ? ? ? proxy.dependsOnOwnProps = getDependsOnOwnProps(props)

? ? ? ? ? ? ? ? //? ? ? ? ? props = proxy(stateOrDispatch, ownProps)

? ? ? ? ? ? ? ? //? ? ? ? }


? ? ? ? ? ? ? ? //? ? ? ? if (process.env.NODE_ENV !== 'production')

? ? ? ? ? ? ? ? //? ? ? ? ? verifyPlainObject(props, displayName, methodName)

? ? ? ? ? ? ? ? ? ? ? ? ? ? // 此時得到最后的要添加的props屬性

? ? ? ? ? ? ? ? //? ? ? ? return props

? ? ? ? ? ? ? ? //? ? ? }

? ? ? ? ? ? ? ? ? ? ? //? 返回proxy

? ? ? ? ? ? ? ? //? ? ? return proxy

? ? ? ? ? ? ? ? //? ? }

? ? ? ? ? ? ? ? //? }


? ? ? ? // 返回一個initMapStateToProps方法(該方法調(diào)用時返回proxy)

? ? ? ? const initMapStateToProps = match(mapStateToProps,mapStateToPropsFactories,'mapStateToProps')

? ? ? ? const initMapDispatchToProps = match(mapDispatchToProps, mapDispatchToPropsFactories, 'mapDispatchToProps')

? ? ? ? const initMergeProps = match(mergeProps, mergePropsFactories, 'mergeProps')

? ? ? ? // 調(diào)用connectAdvanced钉疫、

? ? ? ? // 參數(shù) selectorFactory 初始化每次props改變時要調(diào)用的方法(返回新的props給被嵌套的控件)

? ? ? ? // 參數(shù) {selector 計算需要的參數(shù)}

? ? ? ? // HOC (Higher-order component)獲取一個組件 返回一個高階組件

? ? ? ? return connectHOC(selectorFactory,{

? ? ? ? ? ? // 實參

? ? ? ? ? ? initMapStateToProps,

? ? ? ? ? ? initMapDispatchToProps,

? ? ? ? ? ? initMergeProps,

? ? ? ? })

? ? }

}

// 將傳入的

function match(arg,factories,name){

? ? for(let i = factories.length -1; i >= 0 ;i--){

? ? ? ? const result = factories[i](arg)

? ? ? ? if(result){

? ? ? ? ? ? return result

? ? ? ? }

? ? }

? ? return (dispatch,options)=>{

? ? ? ? throw new Error

? ? }

}

// connectAdvanced

export default function connectAdvanced(

? ? // 參數(shù)? selectorFactory

? ? // selector function集合,通過state.props.dispatch計算出新的props

? ? // 組合參數(shù) options.pure? pureFinalPropsSelectorFactory: impureFinalPropsSelectorFactory

? ? //?

? ? // export default connnectAdvanced(

? ? ? ? // (dispatch,options)=>

? ? ? ? // (state,props)=>

? ? ? ? // ({ thing:state.things[props.thingId],

? ? ? ? //? ? saveThing: fields => dispatch(actionCreators.saveThing(props.thingId,fields)),

? ? ? ? //? })

? ? // )(YourComponent)

? ? selectorFactory,

? ? // options object:

? ? {

? ? } = {}

){

? ? // 方法體

? ? // 給出入的UI組件wrappedComponent 添加需要props,變成高階組件

? ? // 參數(shù) 基礎(chǔ)組件

? ? return function wrapWithConnect(WrappedComponent){

? ? ? ? // 內(nèi)部類

? ? ? ? class Connect extends Component{

? ? ? ? ? ? constructor(props,context){

? ? ? ? ? ? ? ? super(props,context)

? ? ? ? ? ? ? ? this.version = version

? ? ? ? ? ? ? ? this.state = {}

? ? ? ? ? ? ? ? this.renderCount = 0

? ? ? ? ? ? ? ? this.store = props[storeKey]

? ? ? ? ? ? ? ? this.initSelector();

? ? ? ? ? ? ? ? this.initSubscription();

? ? ? ? ? ? }


? ? ? ? ? ? getChildContext(){

? ? ? ? ? ? ? ? // 傳遞store

? ? ? ? ? ? }

? ? ? ? ? ? componentDidMount(){

? ? ? ? ? ? ? ? //

? ? ? ? ? ? }

? ? ? ? ? ? componentWillReceiveProps(nextProps){


? ? ? ? ? ? }

? ? ? ? ? ? shouldComponentUpdate(){


? ? ? ? ? ? }

? ? ? ? ? ? componentWillUnmount(){


? ? ? ? ? ? }

? ? ? ? ? ? // 方便通過ref操作組件

? ? ? ? ? ? getWrappedInstance(){


? ? ? ? ? ? }

? ? ? ? ? ? setWrappedInstance(){


? ? ? ? ? ? }

? ? ? ? ? ? initSelector(){


? ? ? ? ? ? ? ? const sourceSelector = selectorFactory(this.store.dispatch,selectorFactoryOptions)

? ? ? ? ? ? ? ? this.selector = makeSelectorStateful(sourceSelector,this.store);

? ? ? ? ? ? ? ? // function makeSelectorStateful(sourceSelector, store) {

? ? ? ? ? ? ? ? //? ? // wrap the selector in an object that tracks its results between runs.

? ? ? ? ? ? ? ? //? ? const selector = {

? ? ? ? ? ? ? ? ? ? // 為selector 添加run方法

? ? ? ? ? ? ? ? //? ? ? run: function runComponentSelector(props) {

? ? ? ? ? ? ? ? //? ? ? ? try {

? ? ? ? ? ? ? ? ? ? ? ? ? ? // mergedProps = mergeProps(stateProps, dispatchProps, ownProps)

? ? ? ? ? ? ? ? //? ? ? ? ? const nextProps = sourceSelector(store.getState(), props)

? ? ? ? ? ? ? ? //? ? ? ? ? if (nextProps !== selector.props || selector.error) {

? ? ? ? ? ? ? ? //? ? ? ? ? ? selector.shouldComponentUpdate = true

? ? ? ? ? ? ? ? //? ? ? ? ? ? selector.props = nextProps

? ? ? ? ? ? ? ? //? ? ? ? ? ? selector.error = null

? ? ? ? ? ? ? ? //? ? ? ? ? }

? ? ? ? ? ? ? ? //? ? ? ? } catch (error) {

? ? ? ? ? ? ? ? //? ? ? ? ? selector.shouldComponentUpdate = true

? ? ? ? ? ? ? ? //? ? ? ? ? selector.error = error

? ? ? ? ? ? ? ? //? ? ? ? }

? ? ? ? ? ? ? ? //? ? ? }

? ? ? ? ? ? ? ? //? ? }


? ? ? ? ? ? ? ? //? ? return selector


? ? ? ? ? ? ? ? //? }


? ? ? ? ? ? ? ? // 調(diào)用run(this.props)

? ? ? ? ? ? ? ? // ->sourceSelector(store.getState(), props)

? ? ? ? ? ? ? ? // ->mergedProps = mergeProps(stateProps, dispatchProps, ownProps)

? ? ? ? ? ? ? ? // 傳遞屬性給要封裝的組件

? ? ? ? ? ? ? ? this.selector.run(this.props)

? ? ? ? ? ? }

? ? ? ? ? ? initSubscription(){

? ? ? ? ? ? ? ? this.subscription = new Subscription(this.store,parentSub,this.onStateChanged.bind(this))

? ? ? ? ? ? }

? ? ? ? ? ? onStateChange(){


? ? ? ? ? ? ? ? this.selector.run(this.props)

? ? ? ? ? ? }

? ? ? ? ? ? render(){


? ? ? ? ? ? ? ? return createElement(WrappedComponent,this.addExtraProps(this.selector.props))

? ? ? ? ? ? }

? ? ? ? }



? ? ? ? return hoistStatics(Connect,WrappedComponent)

? ? }

}

// 最后得到的就是新的props

// 1巢价、connect(mapStateToProps,mapDispatchToProps,mergeProps

// 2牲阁、connectHOC(selectorFactory,{

//? ? // initMapStateToProps->initProxySelector->proxy->mapStateToProps 獲得傳入的props

//? ? initMapStateToProps,

//? ? initMapDispatchToProps,

//? ? initMergeProps,

//? ? ...

// })

// 3、connectAdvanced(selectorFactory蹄溉,{...})

// 4咨油、wrapWithConnect(WrappedComponent)?

//? ? ? new Connect()

? ? ? ? ? ? // this.selector.run(this.props)

? ? ? ? ? ? // 調(diào)用run(this.props)

? ? ? ? ? ? // ->sourceSelector(store.getState(), props)

? ? ? ? ? ? // ->mergedProps = mergeProps(stateProps, dispatchProps, ownProps)

? ? ? ? ? ? // 傳遞屬性給要封裝的組件


// 5、hoistStatics(Connect,WrappedComponent)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末柒爵,一起剝皮案震驚了整個濱河市役电,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌棉胀,老刑警劉巖法瑟,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唁奢,居然都是意外死亡霎挟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門麻掸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酥夭,“玉大人,你說我怎么就攤上這事脊奋“颈保” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵诚隙,是天一觀的道長讶隐。 經(jīng)常有香客問我,道長久又,這世上最難降的妖魔是什么巫延? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮地消,結(jié)果婚禮上炉峰,老公的妹妹穿的比我還像新娘。我一直安慰自己脉执,他們只是感情好疼阔,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著适瓦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上会涎,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天宏多,我揣著相機與錄音,去河邊找鬼嗦随。 笑死列荔,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的枚尼。 我是一名探鬼主播贴浙,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼署恍!你這毒婦竟也來了崎溃?” 一聲冷哼從身側(cè)響起盯质,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤呼巷,失蹤者是張志新(化名)和其女友劉穎囱修,沒想到半個月后破镰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡压储,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年宇整,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳞青。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片臂拓。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖孵滞,靈堂內(nèi)的尸體忽然破棺而出坊饶,到底是詐尸還是另有隱情匿级,我是刑警寧澤痘绎,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布尔苦,位于F島的核電站蕉堰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏皿渗。R本人自食惡果不足惜贬养,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一儿礼、第九天 我趴在偏房一處隱蔽的房頂上張望诉字。 院中可真熱鬧,春花似錦墨叛、人聲如沸闯传。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扰肌。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工啦吧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诚啃,地道東北人顾彰。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子流译,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容