美文网首页
模仿react-redux源码实现

模仿react-redux源码实现

作者: key君 | 来源:发表于2019-11-11 09:13 被阅读0次

    原理:

    index.js 用Provider标签包裹<App>,并传入store实例
    MyReactReduxPage:从props结构出属性和方法,在页面实现,导入connect高阶函数
    counterReducer: 传入state和action 返回新的state
    MyReactReduxStore:导入redux的createStore,创建store实例传入counterReducer。
    kReactRedux.js:

    src/pages/MyReactReduxPage.js

    import React, { Component } from "react";
    import { connect } from "../kReactRedux";
    
    class MyReactReduxPage extends Component {
      render() {
        console.log("props", this.props);
        const { counter, add, minus } = this.props;
        return (
          <div>
            <h1>MyReactReduxPage</h1>
            <p>{counter}</p>
            <button onClick={add}>add</button>
            <button onClick={minus}>minus</button>
          </div>
        );
      }
    }
    
    export default connect(
      //mapStateToProps
      state => ({ counter: state }),
      //mapDispatchToProps
      {
        add: () => ({ type: "add" }),
        minus: () => ({ type: "minus" }),
      },
    )(MyReactReduxPage);
    
    

    src/store/MyReactReduxStore.js

    import { createStore } from "redux";
    
    import { counterReducer } from "./counterReducer";
    
    const store = createStore(counterReducer);
    
    export default store;
    
    

    src/store/counterReducer.js

    export function counterReducer(state = 0, action) {
      switch (action.type) {
        case "add":
          return state + 1;
        case "minus":
          return state - 1;
        default:
          return state;
      }
    }
    
    

    src/kReactRedux.js

    import React, { useState, useContext, useEffect } from "react";
    // import { bindActionCreators } from "redux";
    
    const Context = React.createContext();
    
    export function Provider({ store, children }) {
      return <Context.Provider value={store}>{children}</Context.Provider>;
    }
    
    export const connect = (
      mapStateToProps = state => state,
      mapDispatchToProps = {},
    ) => Cmp => props => {
      const store = useContext(Context);
      const getMoreProps = () => {
        const stateProps = mapStateToProps(store.getState());
        const dispatchProps = bindActionCreators(
          mapDispatchToProps,
          store.dispatch,
        );
        return {
          ...stateProps,
          ...dispatchProps,
        };
      };
      useEffect(() => {
        store.subscribe(() => {
          setMoreProps({ ...moreProps, ...getMoreProps() });
        });
      }, []);
      const [moreProps, setMoreProps] = useState(getMoreProps());
      return <Cmp {...props} {...moreProps} />;
    };
    
    function bindActionCreator(creator, dispatch) {
      return (...args) => dispatch(creator(...args));
    }
    //{add: ()=>({type:'add'}), minus: ()=>({type: 'minus})
    function bindActionCreators(actionCreators, dispatch) {
      let obj = {};
      for (let key in actionCreators) {
        obj[key] = bindActionCreator(actionCreators[key], dispatch);
      }
      return obj;
    }
    
    

    相关文章

      网友评论

          本文标题:模仿react-redux源码实现

          本文链接:https://www.haomeiwen.com/subject/ntuebctx.html