React ref.current为null

Tho*_*ore 7 ref reactjs

我正在使用具有可变时间范围的议程/日历应用程序。要显示当前时间的一行并显示已进行的约会块,我需要计算给定时间范围内一分钟对应多少像素。

因此,例如:如果议程在上午7点开始,在下午5点结束,则总时间为10小时。假设日历的正文高度为1000像素。这意味着每小时代表100像素,每分钟代表1.66像素。

如果当前时间是下午3点。我们距议程开始只有480分钟的路程。这意味着显示当前时间的行应该在距日历正文顶部79.68像素(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>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

Tom*_*ney 6

因此,关于ref的事情是不能保证在首次渲染时设置它们。您可以确定它们在设置期间和之后都已设置,componentDidMount因此您有两种方法。

您可以使用回调样式ref并基于此设置状态。例如,您可以传递对类似的函数的引用,而不是将ref作为prop传递给prop,this.handleRef它将在其中执行一些逻辑:

  handleRef = r => {
    this.setState({ bodyHeight: r.clientHeight})
    this.calendarBodyRef .current = r;
  };
Run Code Online (Sandbox Code Playgroud)

或者,您可以保留当前设置,但必须将其转移clientHeight到生命周期功能,例如:

  componentDidMount() {
    this.setState({ bodyHeight: this.calendarBodyRef .current.clientHeight });
  }
Run Code Online (Sandbox Code Playgroud)

最终,您不能像这样立即读取ref的当前值,必须在渲染后检查它,然后读取bodyHeightfrom状态。

  • 我的意思是,如果您愿意,您完全可以做到这一点,但是这样的设计可能会变得非常脆弱,因为您可能会遇到诸如共享相同 id 的组件的多个实例呈现之类的问题,并且它可能会使重构或泛化组件有点烦人。 (3认同)

小智 6

您可以使用 ref 回调函数。在这种情况下,您不需要使用“React-createRef()”。

<tbody ref={this.calendarBodyRef}>
...
calendarBodyRef = (e) => {
console.log(e)
}
Run Code Online (Sandbox Code Playgroud)

您将取回 DOM 元素,因此不需要使用“当前”。