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

模仿react-redux源码实现

作者: key君 | 来源:发表于2019-11-05 20:47 被阅读0次

    kReactRedux.js: 引入useContext,导出Provider函数,实际是用context.Provider包裹的,传入store
    导出connect函数:获取store
    getMoreProps: 返回一个带state的值和带type的dispatch方法的对象
    bindActionCreators: 生成一个actionType:dispatch函数的对象
    bindActionCreator:dispatch方法包裹一层

    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);
    
    

    index.js

    import React from "react";
    import ReactDOM from "react-dom";
    import "./index.css";
    import App from "./App";
    import store from "./store/MyReactReduxStore";
    import { Provider } from "./kReactRedux";
    
    // import store from "./store/ReduxStore";
    // import store from "./store/ReactReduxStore";
    // import { Provider } from "react-redux";
    
    // const render = () => {
    //   ReactDOM.render(<App />, document.getElementById("root"));
    // };
    
    // render();
    
    // store.subscribe(render);
    
    ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById("root"),
    );
    
    // ReactDOM.render(<App />, document.getElementById("root"));
    
    

    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 = () => {
        //state => ({ counter: state }),
        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());
      console.log(moreProps);
      
      return <Cmp {...props} {...moreProps} />;
    };
    
    function bindActionCreator(creator, dispatch) {
    //dispatch((creator, dispatch) => ({ type: "add" }))
      return (...args) => dispatch(creator(...args));
    }
    //{add: ()=>({type:'add'}), minus: ()=>({type: 'minus})
    function bindActionCreators(actionCreators, dispatch) {
    //actionCreators   {
    //     add: () => ({ type: "add" }),
    //     minus: () => ({ type: "minus" }),
    //   }
      let obj = {};
      //{add:dispatch方法}
      for (let key in actionCreators) {
        obj[key] = bindActionCreator(actionCreators[key], dispatch);
        // console.log(actionCreators[key]);
        
      }
      return obj;
    }
    
    

    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;
      }
    }
    
    

    相关文章

      网友评论

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

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