zoukankan      html  css  js  c++  java
  • 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))
    }
  • 相关阅读:
    C#模拟百度登录并到指定网站评论回帖(一)
    4张图看明白用户、权限和租户的关系
    我的微服务之路
    IT部门不应该是一个后勤部门
    一个值只有0和1的字段,到底要不要建索引?
    论程序员的自我修养
    RBAC权限管理系统数据模型
    有史以来功能最全,使用最简单的excel导入/导出工具
    一个完全平均分布的固定长度随机数发生器
    基于WCF的RESTFul WebAPI如何对传输内容实现压缩
  • 原文地址:https://www.cnblogs.com/lisiyang/p/13131385.html
Copyright © 2011-2022 走看看