反应 ref.current 为空
React ref.current is null
我正在开发一个具有可变时间范围的 agenda/calendar 应用程序。要显示当前时间的一行并显示已进行的约会的块,我需要计算给定时间范围内一分钟对应的像素数。
例如:如果议程从早上 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>
);
}
}
所以关于 refs 的事情是它们不能保证在第一次渲染时设置。您可以确定它们是在 componentDidMount
期间和之后设置的,因此您有两种前进方式。
您可以使用回调样式 ref 并基于它设置状态。例如。您可以传递对 this.handleRef
之类的函数的引用,而不是将您的 ref 作为 prop 传递,它会在其中执行一些逻辑:
handleRef = r => {
this.setState({ bodyHeight: r.clientHeight})
this.calendarBodyRef.current = r;
};
或者,您可以保留当前设置,但必须将 clientHeight
位移动到生命周期函数,例如:
componentDidMount() {
this.setState({ bodyHeight: this.calendarBodyRef.current.clientHeight });
}
最终,您不能像那样立即读取 ref 的当前值,您必须在渲染后检查它,然后从状态中读取 bodyHeight
。
如果首选避免在组件状态下存储计算出的身高,那么另一种方法是引入第二个 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()
}
}
此方法在 componentDidMount()
生命周期挂钩期间调用 displayCurrentTimeLine()
(它本身在第一个 render()
之后调用)以确保两个 refs
都已完全初始化,在组件逻辑在 displayCurrentTimeLine()
中与它们交互之前。
希望对您有所帮助!
您可以使用 ref 回调函数。在这种情况下,您不需要使用“React-createRef()”。
<tbody ref={this.calendarBodyRef}>
...
calendarBodyRef = (e) => {
console.log(e)
}
您将取回 DOM 元素,因此不需要使用“current”。
如果您正在使用 react-redux
并将您的组件包装在 connect
函数中,那么您需要像这样传递第四个参数,即 forwardRef。
connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})
希望对您有所帮助。
我正在开发一个具有可变时间范围的 agenda/calendar 应用程序。要显示当前时间的一行并显示已进行的约会的块,我需要计算给定时间范围内一分钟对应的像素数。
例如:如果议程从早上 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>
);
}
}
所以关于 refs 的事情是它们不能保证在第一次渲染时设置。您可以确定它们是在 componentDidMount
期间和之后设置的,因此您有两种前进方式。
您可以使用回调样式 ref 并基于它设置状态。例如。您可以传递对 this.handleRef
之类的函数的引用,而不是将您的 ref 作为 prop 传递,它会在其中执行一些逻辑:
handleRef = r => {
this.setState({ bodyHeight: r.clientHeight})
this.calendarBodyRef.current = r;
};
或者,您可以保留当前设置,但必须将 clientHeight
位移动到生命周期函数,例如:
componentDidMount() {
this.setState({ bodyHeight: this.calendarBodyRef.current.clientHeight });
}
最终,您不能像那样立即读取 ref 的当前值,您必须在渲染后检查它,然后从状态中读取 bodyHeight
。
如果首选避免在组件状态下存储计算出的身高,那么另一种方法是引入第二个 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()
}
}
此方法在 componentDidMount()
生命周期挂钩期间调用 displayCurrentTimeLine()
(它本身在第一个 render()
之后调用)以确保两个 refs
都已完全初始化,在组件逻辑在 displayCurrentTimeLine()
中与它们交互之前。
希望对您有所帮助!
您可以使用 ref 回调函数。在这种情况下,您不需要使用“React-createRef()”。
<tbody ref={this.calendarBodyRef}>
...
calendarBodyRef = (e) => {
console.log(e)
}
您将取回 DOM 元素,因此不需要使用“current”。
如果您正在使用 react-redux
并将您的组件包装在 connect
函数中,那么您需要像这样传递第四个参数,即 forwardRef。
connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})
希望对您有所帮助。