我正在尝试创建一个通用组件,我可以在其他应用程序中重用它。我需要知道渲染后组件的宽度,以便我可以修改组件的内容。
我一直在尝试使用不同的生命周期而没有成功。
componentDidUpdate() {
console.log('width', this.element.offsetWidth);
}
render() {
return (
<div ref={(element) => {this.element = element }} />
);
}
当我尝试这个时,我得到了屏幕的宽度,但如果我改变窗口的大小,我得到组件的宽度。请参阅Chrome日志:
ComponentDidMount在渲染之前执行,因此this.element
为undefined
。
我还尝试使用npm中的不同库来解决这个问题而没有运气。
更多信息:组件必须在不同宽度的Bootstrap列中工作。
render() {
<Row>
<Col sm={3} />
<MyComponent />
</Col>
<Col sm={9} />
<MyComponent />
</Col>
<Row>
}
澄清我不想调整窗口大小,我为不清楚而道歉。我提到调整大小的唯一原因是,当DOM已经创建并且我调整大小时,我在offsetWidth
中得到了正确的值。我正在寻找一种解决方案,我可以在不调整大小的情况下获得正确的值。无论是后期渲染函数调用,侦听器,一些反应魔法还是其他解决方案。我的问题是我对虚拟与真实DOM缺乏了解。
答案 0 :(得分:4)
我无法用这里给出的答案解决这个问题。我只获得了浏览器窗口的宽度而不是其中的组件。经过一些研究,看起来我的渲染中有鸡或鸡蛋问题。经过一些研究,我发现dirty
解决了这个问题。
react-sizeme
首次渲染时会生成以下内容
答案 1 :(得分:1)
如果您需要保持组件宽度状态,您可以执行以下操作:
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。 或者,您可以更新附加到类的边界框,并从其他地方获取状态。
componentDidUpdate(){
this.boundingBox = this.element.getBoundingClientRect();
};
答案 2 :(得分:1)
虽然这不是您问题的直接答案,但它是您的问题的解决方案,不会在您的组件中添加调整大小和脏逻辑。
我推荐像https://github.com/digidem/react-dimensions这样的东西 - 这是一个HOC包装器,会收听全局调整大小事件并向你发送道具 - containerWidth
和containerHeight
- 我倾向于使用它当使用SVG,画布和数据网格时需要保持响应并需要知道元素的大小。
至于生命周期 - 像componentDidUpdate
这样的事情可能不会像你想象的那样。山是一次性的。阅读此评论 - https://github.com/facebook/react/issues/2659#issuecomment-66165159