像我之前的许多人一样(我已经阅读了相关的帖子,没有找到答案),我在这段代码中做错了什么:
import React, { Component } from 'react';
export class InfoPaneArrow extends Component<InfoPaneArrowProps> {
infoPaneRef: React.RefObject<HTMLDivElement>;
positionRef: React.RefObject<HTMLDivElement>;
constructor(props: InfoPaneArrowProps) {
super(props);
this.positionRef = React.createRef();
this.infoPaneRef = React.createRef();
}
render() {
const markerBox = this.positionRef?.current?.getBoundingClientRect();
const paneBox = this.infoPaneRef?.current?.getBoundingClientRect();
const outerClass = { /* other code using markerBox & paneBox positions */ };
const innerClass = { /* you get the idea */ };
const arrowClass = { /* ... */ };
const arrowStyle = { /* ... */ };
return (
<div
className={outerClass}
ref={this.positionRef}
>
<div
className={innerClass}
ref={this.infoPaneRef}
>
{this.props.children}
<div
className={arrowClass}
style={arrowStyle}
/>
</div>
</div>
);
}
}
我认为我的问题可能是我在渲染完成之前使用refs,因为infoPaneRef.current
和positionRef.current
总是null -但我需要div
s(和窗口)的坐标来做一些数学运算,并确定是否要重新定位div(因此它始终停留在屏幕上)以及div的哪一边应该渲染(重新定位后)。
知道我在这里做错了什么以及如何纠正吗?
我想你猜对了。在安装(第一次渲染)期间,ref.current为null。您需要在挂载组件后的下一个呈现周期中执行您的逻辑。为了实现这一点,你可以把markerBox
和paneBox
在一个状态,在componentDidMount方法中设置它们,并使你的逻辑依赖于这些状态属性。
在构造函数中添加:
this.state = {markerBox: undefined, paneBox: undefined};
为类添加方法:
componentDidMount() {
const markerBox = this.positionRef?.current?.getBoundingClientRect();
const paneBox = this.infoPaneRef?.current?.getBoundingClientRect();
this.setState({markerBox, paneBox});
}
不要忘记从markerBox
和paneBox
变量的呈现方法定义中删除,并通过this.state.markerBox
和this.state.paneBox
使用状态属性。