如何获取:在 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.element
是 undefined
。
我也曾尝试使用 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 包装器,会监听全局调整大小事件并向你发送道具——containerWidth
和 containerHeight
——我倾向于使用在使用 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);
首次渲染时会产生以下内容
我正在尝试创建一个通用组件,我可以在其他应用程序中重复使用它。我需要知道渲染后组件的宽度,以便我可以修改组件的内容。
我一直在尝试在 React 中使用不同的生命周期,但没有成功。
componentDidUpdate() {
console.log('width', this.element.offsetWidth);
}
render() {
return (
<div ref={(element) => {this.element = element }} />
);
}
当我尝试这个时,我得到了屏幕的宽度,但是如果我改变 window 的大小,我得到了组件的宽度。查看 Chrome 日志:
ComponentDidMount 在渲染之前执行,所以 this.element
是 undefined
。
我也曾尝试使用 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 包装器,会监听全局调整大小事件并向你发送道具——containerWidth
和 containerHeight
——我倾向于使用在使用 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);
首次渲染时会产生以下内容