如何获取:在 React 中渲染后的组件宽度

How to Get: Component Width After Render in React

我正在尝试创建一个通用组件,我可以在其他应用程序中重复使用它。我需要知道渲染后组件的宽度,以便我可以修改组件的内容。

我一直在尝试在 React 中使用不同的生命周期,但没有成功。

componentDidUpdate() {
  console.log('width', this.element.offsetWidth);
}

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

当我尝试这个时,我得到了屏幕的宽度,但是如果我改变 window 的大小,我得到了组件的宽度。查看 Chrome 日志:

ComponentDidMount 在渲染之前执行,所以 this.elementundefined

我也曾尝试使用 npm 的不同库来解决这个问题,但没有成功。

更多信息:组件必须在不同宽度的 Bootstrap 列中工作。

render() {
  <Row>
    <Col sm={3} />
      <MyComponent />
    </Col>
    <Col sm={9} />
      <MyComponent />
    </Col>
  <Row>
}

澄清 我不想调整 window 的大小,很抱歉不清楚。我提到调整大小的唯一原因是当创建 DOM 并调整大小时,我在 offsetWidth 中得到正确的值。我正在寻找一种无需调整大小即可获得正确值的解决方案。 post 渲染函数调用、监听器、一些反应魔法或其他解决方案。我的问题是我对虚拟与真实缺乏了解 DOM。

如果您需要保持组件宽度状态,您可以这样做:

componentDidMount(){ 

          this.boundingBox = this.element.getBoundingClientRect();

          this.setState({ 
              width:this.boundingBox.width
          }); 

          Observable.fromEvent(this.element,"resize")
          .subscribe(
              () => { 
                this.boundingBox = this.element.getBoundingClientRect();  
                this.setState({ 
                    width:this.boundingBox.width
                }); 
              }
          );

};    

您可以将 Observable 替换为事件侦听器。 或者,您可以更新附加到 class 的边界框并从其他地方导出状态。

componentDidUpdate(){ 
          this.boundingBox = this.element.getBoundingClientRect();
};     

虽然这不是您问题的直接答案,但它是您问题的解决方案,不会在组件内部添加调整大小和脏逻辑。

我会推荐类似 https://github.com/digidem/react-dimensions 的东西——它是一个 HOC 包装器,会监听全局调整大小事件并向你发送道具——containerWidthcontainerHeight——我倾向于使用在使用 SVG、canvas 和反应中的数据网格时,需要保持响应并需要知道元素的大小。

至于生命周期 - componentDidUpdate 之类的东西可能不会按照您认为的方式运行。芒特是一次性的。阅读此评论 - https://github.com/facebook/react/issues/2659#issuecomment-66165159

我无法根据此处给出的答案解决此问题。我只得到浏览器的宽度 window 而不是其中的组件。经过一些研究,看起来我在渲染方面遇到了先有鸡还是先有蛋的问题。经过更多研究,我发现 react-sizeme 可以解决问题。

import React, { Component } from 'react';
import sizeMe from 'react-sizeme';

class MyComponent extends Component {
  render() {
    const { width } = this.props.size;

    return (
      <div style={{
        width: '100%',
        backgroundColor: '#eee',
        textAlign: 'center'
      }}>
        <span>My width is: {Math.floor(width)}px</span>
      </div>
    );
  }
}

export default sizeMe()(MyComponent);

首次渲染时会产生以下内容