react-redux实现原理

App顶级组件

import HomePage from './page/HomePage'
// import { Provider } from 'react-redux'
import { Provider } from './Mreact-redux'
/* 
react-redux  提供两个api :   Provider,connect

Provider组件 内部通过context实现跨层级传值,取到store对象;
connect 是个高阶组件,将指定的mapStateToProps、mapDispatchToProps映射到当前UI组件的props上;
从而实现 redux提供的store对象和react组件结合,数据流处理,更新视图效果。
*/
import store from './store/index'
function App() {
  return (
    <Provider store={store}>
      <div className="App">
        <HomePage />
      </div>
    </Provider>

  );
}
export default App;

子组件-HomePage

import React from 'react'
// import { connect } from 'react-redux'
import { connect } from '../Mreact-redux'

class HomePage extends React.Component {
    constructor(props) {
        super(props)
        this.state = {}
    }
    addCount = () => {
        // this.props.dispatch({ type: 'ADD' })
        this.props.add()
    }

    render() {
        console.log("HomePage--props----", this.props);
        const { count, minus, add } = this.props;
        return (
            <div>
                <h1>HomePage</h1>
                <h2>{count}</h2>
                <button onClick={this.addCount}>add</button>
                <button onClick={minus}>minus</button>
            </div>
        );
    }
}
//connect作用:是一个高阶组件  将store对象的state映射到当前组件的props上
//接收两个参数
export default connect(
    // mapStateToProps  Function (state,ownProps)
    state => ({ count: state }),
    //mapDispatchToProps  Object / Function   如果不指定mapDispatchToProps,默认props会被注入dispatch
    {
        add: () => ({ type: "ADD" }),
        minus: () => ({ type: "MINUS" })
    }
    // dispatch => {
    //     const res = {
    //         add: () => dispatch({ type: "ADD" }),
    //         minus: () => dispatch({ type: "MINUS" })
    //     };
    //     return {
    //         dispatch, ...res
    //     }
    // }

)(HomePage)

react-redux内部实现 Mreact-redux.js

import React from 'react'
// import { bindActionCreators } from 'redux';
const contextVal = React.createContext();
export const connect = (mapStateToProps, mapDispatchToProps) => WrappedComponent => {
    return class extends React.Component {
        static contextType = contextVal;
        constructor(props) {
            super(props);
            this.state = {
                props: {}
            }
        }
        componentDidMount() {
            //this.context 为 store对象
            const { subscribe } = this.context;
            this.updata();
            //订阅getState变化
            subscribe(() => {
                this.updata();
            })
        }
        updata = () => {
            const { getState, dispatch } = this.context;
            let stateProps = mapStateToProps(getState());
            let dispatchProps;
            if (typeof mapDispatchToProps == "object") {
                dispatchProps = bindActionCreators(mapDispatchToProps, dispatch);
            } else if (typeof mapDispatchToProps == "function") {
                dispatchProps = mapDispatchToProps(dispatch);
            } else {
                //没传mapDispatchToProps -- 默认情况
                dispatchProps = { dispatch };
            }
            this.setState({
                props: {
                    ...stateProps, ...dispatchProps
                }
            })
        }
        render() {
            // console.log("this.context-----", this.context);
            return <WrappedComponent {...this.state.props} />
        }
    }
};
export class Provider extends React.Component {
    render() {
        return <contextVal.Provider value={this.props.store}>{this.props.children}</contextVal.Provider>
    }
}
export function bindActionCreators(creators, dispatch) {
    const obj = {};
    for (const key in creators) {
        obj[key] = bindActionCreator(creators[key], dispatch);
    }
    return obj;
}
function bindActionCreator(creator, dispatch) {
    return (...args) => dispatch(creator(...args));
}

redux提供的store对象

import { combineReducers, createStore } from 'redux'

const counterReducer = (state = 0, { type, payload = 1 }) => {
    switch (type) {
        case "ADD":
            return state + payload;
        case "MINUS":
            return state - payload;
        default:
            return state;
    }
};
const store = createStore(counterReducer);
export default store
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值