我正在使用时间范围可变的议程/日历应用程序。要显示当前时间的一行并显示已约会的块,我需要计算给定时间范围内一分钟对应多少像素。
因此,例如:如果议程从早上7点开始,到下午5点结束,则总时间为10小时。假设日历的正文高度为1000像素。这意味着每小时代表100像素,每分钟代表1.66像素。
如果当前时间是下午3点。我们距议程开始只有480分钟的路程。也就是说,显示当前时间的行应位于日历主体顶部的796,8像素(480 * 1,66)处。
计算没有问题,但是获得了议程主体的高度。我当时在考虑使用React Ref来获取高度,但出现错误:ref.current is null
下面的一些代码:
class Calendar extends Component {
calendarBodyRef = React.createRef();
displayCurrentTimeLine = () => {
const bodyHeight = this.calendarBodyRef.current.clientHeight; // current is null
}
render() {
return (
<table>
<thead>{this.displayHeader()}</thead>
<tbody ref={this.calendarBodyRef}>
{this.displayBody()}
{this.displayCurrentTimeLine()}
</tbody>
</table>
);
}
}
答案 0 :(得分:3)
因此,关于ref的事情是不能保证在首次渲染时设置它们。您可以确定它们是在componentDidMount
期间和之后设置的,因此有两种前进的方式。
您可以使用回调样式ref并基于此设置状态。例如。您可以将对诸如this.handleRef
之类的函数的引用传递给它,而不用像prop那样传递引用。
handleRef = r => {
this.setState({ bodyHeight: r.clientHeight})
this.calendarBodyRef .current = r;
};
或者,您可以保留当前设置,但必须将clientHeight
位移至生命周期函数,例如:
componentDidMount() {
this.setState({ bodyHeight: this.calendarBodyRef .current.clientHeight });
}
最终,您不能像这样立即读取ref的当前值,必须在渲染后检查它,然后从状态读取bodyHeight
。
答案 1 :(得分:1)
您可以使用ref回调函数。在这种情况下,您无需使用“ React-createRef()”。
<tbody ref={this.calendarBodyRef}>
...
calendarBodyRef = (e) => {
console.log(e)
}
您将获得DOM元素,因此不需要使用“当前”。
答案 2 :(得分:0)
如果最好避免以组件状态存储计算出的身高,则另一种方法是像这样引入第二个ref
(即elementDisplayHeightRef
):
class Calendar extends React.Component {
/* Create a ref for the body */
calendarBodyRef = React.createRef();
/* Create a ref for element where height will be displayed */
elementDisplayHeightRef = React.createRef();
displayCurrentTimeLine = () => {
/* Calculate body height from ref */
const bodyHeight = this.calendarBodyRef.current.clientHeight;
/* Update display */
this.elementDisplayHeightRef.current.innerText = `bodyHeight:${bodyHeight}`
}
render() {
return (
<table>
<thead></thead>
<tbody ref={this.calendarBodyRef}>
<td><td>Some row</td></td>
{/* Bind display ref */ }
<tr><td ref={this.elementDisplayHeightRef}></td></tr>
</tbody>
</table>
);
}
/* Add did mount life cycle hook, and trigger display of body height */
componentDidMount() {
this.displayCurrentTimeLine()
}
}
此方法会在displayCurrentTimeLine()
生命周期挂钩期间调用componentDidMount()
(其本身在第一个render()
之后被调用),以确保在refs
之前完全初始化两个displayCurrentTimeLine()
组件逻辑在es.mysite.com
中与它们交互。
希望有帮助!
答案 3 :(得分:0)
如果您使用 react-redux
并将组件包装在 connect
函数中,那么您需要传递第四个参数,即像这样的 forwardRef。
connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})
希望对您有所帮助。