美文网首页
react_16Hooks_二(代码优化与第三方库使用)

react_16Hooks_二(代码优化与第三方库使用)

作者: 小话001 | 来源:发表于2022-10-26 15:03 被阅读0次

    接上一篇优化home.js与about.js中的代码:


    思路.jpg
    优化思路.jpg

    优化后about.js

    import React from "react";
    import { connect } from "../utils/connect";
    
    import { decAction, subAction } from "../store/actionCreators";
    
    function About(props) {
      return (
        <div>
          <hr />
          <h1>About</h1>
          <h2>当前计数: {props.counter}</h2>
          <button onClick={(e) => props.decrement()}>-1</button>
          <button onClick={(e) => props.subNumber(5)}>-5</button>
        </div>
      );
    }
    
    const mapStateToProps = (state) => {
      return {
        counter: state.counter,
      };
    };
    const mapDispatchToProps = (dispatch) => {
      return {
        decrement: function () {
          dispatch(decAction());
        },
        subNumber: function (num) {
          dispatch(subAction(num));
        },
      };
    };
    
    export default connect(mapStateToProps, mapDispatchToProps)(About);
    

    优化后home.js与about.js一样,只是调用的action不一样;

    //类组件home
    import React, { PureComponent } from 'react';
    
    import {connect} from '../utils/connect';
    import {  incAction,  addAction } from '../store/actionCreators'
    
    class Home extends PureComponent {
      render() {
        return (
          <div>
            <h1>Home</h1>
            <h2>当前计数: {this.props.counter}</h2>
            <button onClick={e => this.props.increment()}>+1</button>
            <button onClick={e => this.props.addNumber(5)}>+5</button>
          </div>
        )
      }
    }
    
    const mapStateToProps = state => ({
      counter: state.counter
    })
    
    const mapDispatchToProps = dispatch => ({
      increment() {
        dispatch(incAction());
      },
      addNumber(num) {
        dispatch(addAction(num));
      }
    })
    
    export default connect(mapStateToProps, mapDispatchToProps)(Home);
    

    utils/connect.js

    import React, { PureComponent } from "react";
    
    import  store  from '../store';
    
    export function connect(mapStateToProps, mapDispachToProp) {
      return function enhanceHOC(WrappedComponent) {
       return class extends PureComponent {
          constructor(props) {
            super(props);
            this.state = {
              storeState: mapStateToProps(store.getState())
            }
          }
    
          componentDidMount() {
            this.unsubscribe = store.subscribe(() => {
              this.setState({
                storeState: mapStateToProps(store.getState())
              })
            })
          }
    
          componentWillUnmount() {
            this.unsubscribe();
          }
    
          render() {
            return <WrappedComponent {...this.props}
              {...mapStateToProps(store.getState())}
              {...mapDispachToProp(store.dispatch)} />
          }
        }
      }
    }
    

    至此,封装完成了
    思考:不止当前项目需要connect函数,那么最好的办法是把它封装成库,然后上传到npm,但是,当前还不够独立,因为它依赖了外部引入的store,也就是对业务逻辑有了依赖。问题:依然需要拿到store,但是不能通过导入的方式了。

    解决方案:

    手动封装库文件

    utils/context.js

    import React from 'react';
    
    const StoreContext = React.createContext(); 
    
    export {
      StoreContext
    }
    

    utils/connect.js

    import React, { PureComponent } from "react";
    
    import { StoreContext } from './context';
    
    export function connect(mapStateToProps, mapDispachToProp) {
      return function enhanceHOC(WrappedComponent) {
        class EnhanceComponent extends PureComponent {
          constructor(props, context) {
            super(props, context);
    
            this.state = {
              storeState: mapStateToProps(context.getState())
            }
          }
    
          componentDidMount() {
            this.unsubscribe = this.context.subscribe(() => {
              this.setState({
                storeState: mapStateToProps(this.context.getState())
              })
            })
          }
    
          componentWillUnmount() {
            this.unsubscribe();
          }
    
          render() {
            return <WrappedComponent {...this.props}
              {...mapStateToProps(this.context.getState())}
              {...mapDispachToProp(this.context.dispatch)} />
          }
        }
    
        EnhanceComponent.contextType = StoreContext;
    
        return EnhanceComponent;
      }
    }
    

    src/index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    import store from './store';
    import { StoreContext } from './utils/context';
    import App from './App';
    
    ReactDOM.render(
      <StoreContext.Provider value={store}>
        <App />
      </StoreContext.Provider>,
      document.getElementById('root')
    );
    

    至此,到时候封装库的话只需要导出context与connect就行。

    直接用第三方库文件

    yarn add react-redux

    src/index.js
    对比自己封装的,使用时候会有一点点不一样

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    import store from './store';
    
    // import { StoreContext } from './utils/context';
    import { Provider } from 'react-redux';
    
    import App from './App';
    
    ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('root')
    );
    

    pages/about.js与pages/home.js,均使用第三方的connect就行

    import React from "react";
    // import { connect } from "../utils/connect";
    import { connect } from 'react-redux';
    
    import { decAction, subAction } from "../store/actionCreators";
    
    function About(props) {
      return (
        <div>
          <hr />
          <h1>About</h1>
          <h2>当前计数: {props.counter}</h2>
          <button onClick={(e) => props.decrement()}>-1</button>
          <button onClick={(e) => props.subNumber(5)}>-5</button>
        </div>
      );
    }
    
    const mapStateToProps = (state) => {
      return {
        counter: state.counter,
      };
    };
    const mapDispatchToProps = (dispatch) => {
      return {
        decrement: function () {
          dispatch(decAction());
        },
        subNumber: function (num) {
          dispatch(subAction(num));
        },
      };
    };
    
    export default connect(mapStateToProps, mapDispatchToProps)(About);
    

    相关文章

      网友评论

          本文标题:react_16Hooks_二(代码优化与第三方库使用)

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