【问题标题】:React - get element.getBoundingClientRect() after window resizeReact - 窗口调整大小后获取 element.getBoundingClientRect()
【发布时间】:2020-05-30 13:07:54
【问题描述】:

我有一个类需要获取 DOM 元素的大小。它运行良好,但是当我调整窗口大小时,它不会更新,直到我更改应用程序中的状态,强制重新渲染。我尝试将this.forceUpdate 添加到componentDidMount() 中的'resize' 事件侦听器,但没有成功。也许我做错了什么?理想情况下,无论如何我都想避免使用this.forceUpdate 来影响性能。有什么解决方法吗?提前致谢!

我的代码:

class MyComponent extends React.Component {
  state = { x: 0, y: 0 }

  refCallback = (element) => {
    if (!element) {
      return
    }
    const { x, y } = element.getBoundingClientRect()
    this.setState({ x, y })
  }

  render() {
    console.log('STATE:', this.state) // Outputs the correct x and y values.
    return (
      <div ref={this.refCallback}>
        <button>Hello world</button>
      </div>
    )
  }
}

【问题讨论】:

  • 您是否在window 对象上添加了resize 事件侦听器?这是触发浏览器调整大小事件的元素。您可以在这个问题中看到example 说明如何使用钩子完成此操作,但基本上相同的方法可以用于类组件,您可以在其中编写一个更新状态并将其附加到窗口的函数。
  • @ChrisB。我已经尝试过了

标签: reactjs


【解决方案1】:

如果您想在窗口调整大小时测量组件中的某些元素,它看起来像这样:

class MyComponent extends React.Component {
  state = {
    x: 0,
    y: 0,
  };

  element = React.createRef();

  onWindowResize = () => {
    if (this.element.current) {
      const {x, y} = this.element.current.getBoundingClientRect();
      this.setState({x, y}, () => {
        console.log(this.state);
      });
    }
  };

  componentDidMount() {
    window.addEventListener('resize', this.onWindowResize);
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.onWindowResize);
  }

  render() {
    return (
      <div ref={this.element}>
        <button>Hello, World</button>
      </div>
    );
  }
}

这里的诀窍是,当元素最初添加到 DOM 时,您的 ref 回调仅被调用一次。如果您想在调整窗口大小时更新状态,您将需要一个'resize' 事件处理程序。

【讨论】:

    【解决方案2】:

    发生这种情况是因为:

    来自the React documentation

    为 DOM 元素添加 Ref

    React 支持一个可以附加到任何组件的特殊属性。 ref属性带回调函数,组件挂载或卸载后立即执行回调。

    React 会在组件挂载时使用 DOM 元素调用 ref 回调,并在卸载时使用 null 调用它。

    所以,这就是为什么当你刷新你会得到价值。为了克服这个问题,你可以这样做:

    import React from "react";
    
    class MyComponent extends React.Component {
      constructor(props) {
        super(props);
        this.myRef = React.createRef();
        this.state = {
          x: 0,
          y: 0
        };
      }
    
      updateDimensions = () => {
        if (this.myRef.current) {
          const {x, y} = this.myRef.current.getBoundingClientRect();
          this.setState({ x, y });
        }
      };
      componentDidMount() {
        window.addEventListener("resize", this.updateDimensions);
      }
      componentWillUnmount() {
        window.removeEventListener("resize", this.updateDimensions);
      }
    
      render() {
        console.log("STATE:", this.state); // Outputs the correct x and y values.
        return (
          <div ref={this.myRef}>
            <button>Hello world</button>
          </div>
        );
      }
    }
    
    export default MyComponent;
    

    希望这对你有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-02
      • 2013-02-22
      • 2012-07-29
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      相关资源
      最近更新 更多