002_学习redux以及react_redux

一、redux之自定义createStore

/**
 * 自定义Store,返回一个对象
 */
export function createStore(reducer) {
    let state = reducer(undefined, { type: "redux/init@@" })
    //添加获取获取state方法
    function getState() {
        return state
    }

    //定义分发action方法
    function dispatch(action) {
        state = reducer(state, action)
        listeners.forEach(listener => listener())
    }

    let listeners = []
    //定义数据更新时的回调
    function subscribe(listener) {
        listeners.push(listener)
    }

    return { getState, dispatch, subscribe }
}

二、redux之自定义combineReducers

/**
 * 自定义联合combineReducers
 * {
 *  count:count相关的reducer,
 *  user:user相关的reducer
 * }。
 * 因为reducers是一个对象的形式,那么通过遍历reducers的属性
 */
export function combineReducers(reducers) {
    //如果state接受到的参数是undefined,那么state参数将会使用默认值
    return (state = {}, action) => {
        return Object.keys(reducers).reduce((pre, key) => {
            //将各个reducer的运行结果封装到对象中
            pre[key] = reducers[key](state[key], action)
            return pre
        }, {})
    }
}

三、react-redux自定义

import React, { Component } from "react"
import PropTypes from 'prop-types'


//定义Context用于祖组件与后代组件通信
const StoreContext = React.createContext()
/**
 * Provider必须要接受一个store的属性
 */
export class Provider extends Component {
    static propTypes = {
        store: PropTypes.object.isRequired
    }

    render() {
        return (
            // 将外部接受到的store提供给后代组件
            <StoreContext.Provider value={this.props.store}>
                {this.props.children}
            </StoreContext.Provider>
        )
    }
}

/**
 * connect是一个高阶组件函数
 * @param {*} mapStateToProps 将state属性转化为Props 
 * @param {*} mapDispatchToProps 将dispatch转化为Props
 * @returns 
 */
export function connect(mapStateToProps, mapDispatchToProps) {
    return (UIComponent) => {
        return class ContainerComponent extends Component {
            static contextType = StoreContext;

            constructor(props, context) {
                super(props)
                const { getState, dispatch, subscribe } = context
                const stateProps = mapStateToProps(getState())
                /**
                 * 对象解构赋值给state属性值
                 */
                this.state = { ...stateProps }
                /**
                 * 将封装好的分发action的方法传递给UI组件做属性.
                 * 因为其不用更新,所以直接添加给ContainerComponent实例
                 */
                if (typeof mapDispatchToProps === 'function') {
                    this.dispatchProps = mapDispatchToProps(dispatch)
                } else {
                    this.dispatchProps = Object.keys(mapDispatchToProps).reduce((pre, key) => {
                        //第一个...args用来接收参数,第二个...args用来传递参数,从而实现参数后传
                        pre[key] = (...args) => dispatch(mapDispatchToProps[key](...args))
                        return pre
                    }, {})
                }

                /**
                 * 添加redux中state变化的监听
                 */
                subscribe(() => {
                    const stateProps = mapStateToProps(getState())
                    this.setState({ ...stateProps })
                })
            }

            render() {
                return <UIComponent {...this.state} {...this.dispatchProps} />
            }
        }
    }
}

源码地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值