手写connect

作者: 未路过 | 来源:发表于2022-10-31 14:41 被阅读0次

    使用react-redux中的

    
    function mapStateToProps(state) {
      console.log("查看state");
      console.log(state);
      return { count: state.count, personList: state.person };
    }
    
    function mapDispatchToProps(dispatch) {
      return {
        increment: (number) => dispatch(addNumber(number)),
        decrement: (number) => dispatch(deNumber(number)),
        asyncIncrement: (number) => dispatch(addNumber(number)),
      };
    }
    
    const CountContainer = connect(mapStateToProps, mapDispatchToProps)(Count);
    
    export default CountContainer;
    

    使用的时候
    <CountContainer> </CountContainer>

    react-redux就做了两件事,connect和provider,实时监测state更新
    给组件套了一个壳子,接受了一个store而已。

    RTK就是给store套了个壳子。reducer的写法改变,其他没啥变化。

    简单实现1
    ``js
    //connect的参数
    //参数1:函数
    //参数2:函数
    //返回值:函数 =》接受一个高阶组件,返回高阶组件
    import { PureComponent } from "react";
    import store from "../store/store";
    export function connect(mapStateToProps, mapDispatchToProps) {
    return function (WrapperComponent) {
    class NewComponent extends PureComponent {
    render() {
    const stateObj = mapStateToProps(store.getState());
    const dispatchObj = mapDispatchToProps(store.dispatch);

        return (
          <WrapperComponent
            {...this.props}
            {...stateObj}
            {...dispatchObj}
          ></WrapperComponent>
        );
      }
    }
    
    return NewComponent;
    

    };
    }

    问题就是state里面状态改变,也不会重新调用render函数
    以前没有react-redcue的时候是使用store.subscribe(()=>{})来监听的,里面
    ```js
    store.subscribe(()=>{
        ReactDOM.render(<App/>,document.getElementById('root'))
    })
    

    强制刷新

    //connect的参数
    //参数1:函数
    //参数2:函数
    //返回值:函数 =》接受一个高阶组件,返回高阶组件
    import { PureComponent } from "react";
    import store from "../store/store";
    export function connect(mapStateToProps, mapDispatchToProps) {
      return function (WrapperComponent) {
        class NewComponent extends PureComponent {
          componentDidMount() {
            store.subscribe(() => {
              this.forceUpdate();
            });
          }
          render() {
            console.log("newComponent render");
            const stateObj = mapStateToProps(store.getState());
            const dispatchObj = mapDispatchToProps(store.dispatch);
    
            return (
              <WrapperComponent
                {...this.props}
                {...stateObj}
                {...dispatchObj}
              ></WrapperComponent>
            );
          }
        }
    
        return NewComponent;
      };
    }
    
    

    使用setstate

    //connect的参数
    //参数1:函数
    //参数2:函数
    //返回值:函数 =》接受一个高阶组件,返回高阶组件
    import { PureComponent } from "react";
    import store from "../store/store";
    export function connect(mapStateToProps, mapDispatchToProps) {
      return function (WrapperComponent) {
        class NewComponent extends PureComponent {
          constructor(props, context) {
            super(props);
            this.state = mapStateToProps(store.getState());
          }
    
          componentDidMount() {
            this.unsubscribe = store.subscribe(() => {
              // this.forceUpdate();
              //没有必要全部刷新。
              //store里面有很多状态,不仅仅是当前使用connect的组件的这个状态,每次其他组件的状态改变,我们的这个组件也要刷新,所以不太好,就是我们的组件中使用的state如果有改变的话,就刷新改组件。也就是mapStateToProps里面使用的state
              this.setState(mapStateToProps(store.getState()));
              //purecomponet浅层拷贝
            });
          }
    
          componentWillUnmount() {
            this.unsubscribe();
          }
          render() {
            console.log("newComponent render");
            const stateObj = mapStateToProps(store.getState());
            const dispatchObj = mapDispatchToProps(store.dispatch);
    
            return (
              <WrapperComponent
                {...this.props}
                {...stateObj}
                {...dispatchObj}
              ></WrapperComponent>
            );
          }
        }
    
        return NewComponent;
      };
    }
    
    

    接下来把store抽离出去
    创建
    src/hoc/StoreContext.js

    import { createContext } from "react";
    
    export const StoreContext = createContext();
    

    创建
    src/hoc/index.js

    export { StoreContext } from "./StoreContext";
    export { connect } from "./connect";
    
    

    index.js

    import React from "react";
    import ReactDOM from "react-dom/client";
    
    import App from "./App";
    import { Provider } from "react-redux";
    import { StoreContext } from "./hoc";
    import store from "./store/store";
    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(
      <Provider store={store}>
        <StoreContext.Provider value={store}>
          <App />
        </StoreContext.Provider>
      </Provider>
    );
    
    

    connect.js

    //connect的参数
    //参数1:函数
    //参数2:函数
    //返回值:函数 =》接受一个高阶组件,返回高阶组件
    import { PureComponent } from "react";
    import { StoreContext } from "./StoreContext";
    export function connect(mapStateToProps, mapDispatchToProps) {
      return function (WrapperComponent) {
        class NewComponent extends PureComponent {
          constructor(props, context) {
            //这个context就是store本身
            super(props);
            this.state = mapStateToProps(context.getState());
          }
    
          componentDidMount() {
            this.unsubscribe = this.context.subscribe(() => {
              // this.forceUpdate();
              //没有必要全部刷新。
              //store里面有很多状态,不仅仅是当前使用connect的组件的这个状态,每次其他组件的状态改变,我们的这个组件也要刷新,所以不太好,就是我们的组件中使用的state如果有改变的话,就刷新改组件。也就是mapStateToProps里面使用的state
              this.setState(mapStateToProps(this.context.getState()));
              //purecomponet浅层拷贝
            });
          }
    
          componentWillUnmount() {
            this.unsubscribe();
          }
          render() {
            const stateObj = mapStateToProps(this.context.getState());
            const dispatchObj = mapDispatchToProps(this.context.dispatch);
    
            return (
              <WrapperComponent
                {...this.props}
                {...stateObj}
                {...dispatchObj}
              ></WrapperComponent>
            );
          }
        }
    
        NewComponent.contextType = StoreContext;
    
        return NewComponent;
      };
    }
    
    image.png

    相关文章

      网友评论

        本文标题:手写connect

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