【问题标题】:Higher Order Component (HOC) and window resize listener高阶组件 (HOC) 和窗口调整大小监听器
【发布时间】:2020-05-04 17:06:58
【问题描述】:

我有以下 HOC,我考虑创建 3 个状态,这些状态将是我的断点

  • 移动
  • 平板电脑
  • 桌面

但我想知道如何在到达断点时将这些状态设置为 true 示例:

  • 手机:小于 767
  • 平板电脑:768到991之间
  • 桌面:992 到 1919 之间
  • 大屏幕:1919 和 2520

然后当到达这些断点之一时,状态将变为 true

另外,我如何才能在我的 HOC 中只传递一个状态(以正确者为准)?

我可以改进这个逻辑吗?

import React from "react";

const withWindowResize = Component => {
  class WrappedComponent extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        height: 0,
        width: 0,
        mobile: false,
        desktop: false,
        tablet: false
      };
      window.addEventListener("resize", this.resizeUpdate);
    }

    componentDidMount() {
      this.update();
    }

    resizeUpdate = () => {
      this.setState({
        height: window.innerHeight,
        width: window.innerWidth
      });
    };

    render() {
      return <Component />;
    }
  }
  return WrappedComponent;
};

export default withWindowResize;

【问题讨论】:

    标签: javascript reactjs dom-events event-listener window-resize


    【解决方案1】:

    有很多方法可以做到这一点,但是按照您的方法,您可以执行以下操作,其中您的状态会根据您上面提供的规范更改为 size 变量。

    这样,您只需将this.state.size 传递给您的组件。

    import React from "react";
    
    const withWindowResize = Component => {
      class WrappedComponent extends React.PureComponent {
        constructor(props) {
          super(props);
    
          this.state = {
            size: this.findSize()
          };
        }
    
        componentDidMount() {
          window.addEventListener("resize", this.resizeUpdate.bind(this)); // initialize your listener
        }
    
        componentWillUnmount() { // remove event listener on component unmount
          window.removeEventListener("resize", this.resizeUpdate.bind(this));
        }
    
        findSize() {
          return window.innerWidth > 1919
              ? "large"
              : window.innerWidth > 992
              ? "desktop"
              : window.innerWidth > 768
              ? "tablet"
              : "mobile"; // find currentSize
        }
    
        resizeUpdate() {
          const currentSize = this.findSize();
    
          this.setState({
            size: currentSize
          });
        }
    
        render() {
          return <Component size={this.state.size} />;
        }
      }
    
      return WrappedComponent;
    };
    
    export default withWindowResize;
    

    请注意,我正在使用React.PureComponent,因为我们不想更改我们的状态并在每次调整窗口大小时重新渲染我们的Component

    这与使用 React.Component 并在使用 this.setState 之前检查相同,如果我们的 currentSize 与我们的状态不同,在更新之前。

    if (currentSize !== this.state.size) {
      this.setState({
        size: currentSize
      });
    }
    

    【讨论】:

    • 我出于某种原因使用了这个,我的应用程序说无法读取道具,我认为我在 emu 应用程序中有一些问题。 function App () { console.log (this.props) return ( ); } export default withWindow (App);
    • 我认为创建上下文更好吗?
    • 如果你使用的是function 作为你的App 而不是一个类,那么你不能从this 访问道具,因为this 是对window 的引用而不是你的组件。试试function App (props) { console.log(props) return &lt;div&gt;&lt;/div&gt; } export default withWindowResize(App);
    • 好的,非常感谢,有没有更清晰的选择?还是您认为这是一个不错的选择?
    • 我认为这种方法最适合您的情况
    猜你喜欢
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 2012-03-31
    • 2013-12-14
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多