redux 源码学习日记

// 聚合函数 用于applymiddleware
function compose(...funs) {
    const len = funs.length;
    if(len === 0) return a => a
    if(len === 1) return funs[0]

    return funs.reduce((left, right) => {
        return (...args) => right(left(...args))
    })
}


// store 原理 
// 返回一个具有 createStore dispatch subscribe方法的对象

// redux 暴露的createStore 方法

const createStore = (reducer, enhancer) => {
// enhancer 是一个增强器 比如中间件 applymiddleware
    if(enhancer) return enhancer(createStore)(reducer)

    let cur = undefined;
    let curlist = []; //存放监听函数
    
    function getState() {
        return cur
    }

    function dispatch(action) {
        cur = reducer(cur, action)
        curlist.map(cl => cl())
    }

    function subscribe(listener) {
        curlist.push(listener)
    }

    dispatch({type:'1111'}) ;//默认状态下  要先触发一次

    return {
        getState, dispatch, subscribe
    }

}

// redux 暴露的 applymiddleware方法
// createStore(reducer, applymiddleware(logger, thunk))

// 起初list 是按照从做向右的方向执行
// 最后的执行结果是右向左执行
const applymiddleware = (...list) => {
    // 接受createStore作为参数 返回一个函数
    return createStore => (...args) => {
        let store = createStore(...args);
        const midApi = {
            getState: store.getState,
            dispatch: store.dispatch
        }
        const chain = list.map( mw => mw(midApi))
        // mw(midApi) 返回一个函数
        const dispatch = compose(...chain)(store.dispatch)

        return {
            ...store, dispatch
        }

    }
    
}

const logger = () => {
    return dispatch => action => {
        return dispatch(action)
    }
}

const thunk = () => {
    return dispatch =>action => {
        if(typeof action === 'function') action()
        dispatch(action)
    }
}
// react-redux 提供provider connect方法
// provider 基于context原理
// connect 将dispatch state映射到props 并订阅变化用于实时刷新

import { connect } from "react-redux";
import { useContext, useState, useEffect } from "react";

const Context = React.createContext();

export const Provider = props => {
    return <Context.Provider value={props.store}>
        {props.children}
    </Context.Provider>
}


export const connect = (
    mapStatetoProps = state => state,
    mapDispatchtoProps = {} // 爱react-redux 中 这个既可以是对象 可以是一个函数 
    ) => {
        return Cmp => {
            return () => {
                const store = useContext(Context)
                const getProps = () => {
                    const stateProps = mapStatetoProps(store.getState())
                    const dispatchProps = bindActionCreators(mapDispatchtoProps, store.dispatch)
                }
                return {
                    ...stateProps, ...dispatchProps
                }
                
                const [props, setProps] = useState({...getProps()})

                useEffect(() => {
                    store.subsribe(() => {
                        setProps({...props, ...getProps()})
                    })

                    return store.unsubscribe()
                }, [])

                return <Cmp {...props}/>
            }
        }
    }

function bindActionCreators(creators, dispatch) {
    return Object.keys(creators).reduceRight((ret, item) => {
        ret[item] = bindActionCreator(creator[item], dispatch)
        return ret
    })
}

function bindActionCreator(creators, dispatch) {
    return (...args)=> dispatch(creators(...args))
}
原文地址:https://www.cnblogs.com/lisiyang/p/13131385.html