You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript strictPropertyInitialization新选项下使用React refs?

Fixing React Refs with TypeScript's strictPropertyInitialization for Bootstrap Popover

When TypeScript’s strictPropertyInitialization flag is enabled, it enforces that all class properties are initialized either at declaration time or in the constructor. This often causes headaches with React refs, since they’re typically assigned later in the render method. Let’s walk through the solutions for your Popover component.

First, let’s assume your component had a ref declared like this (which would trigger the error):

export class Popover extends PureComponent<PopoverProps, object> {
  // This throws an error because popoverRef isn't initialized
  private popoverRef: React.RefObject<HTMLElement>;

  // ... rest of your component code (componentDidMount, render, etc.)
}

Solution 1: Initialize the ref at declaration time

The simplest fix is to initialize the ref immediately when declaring it using React.createRef():

import * as React from "react"
import { PureComponent } from "react";
import { EventUtil } from "appUtil/EventUtil";

export interface PopoverProps extends React.HTMLProps<HTMLElement>{
  popoverTitle: string | Element | Function;
  popoverContent: string | Element | Function;
  container?: string;
  allowDefaultClick?: boolean;
}

export class Popover extends PureComponent<PopoverProps, object> {
  // Initialize ref right here to satisfy TypeScript
  private popoverRef = React.createRef<HTMLElement>();

  componentDidMount() {
    // Safely access the ref (always check if current exists!)
    if (this.popoverRef.current) {
      // Initialize Bootstrap popover
      $(this.popoverRef.current).popover({
        title: this.props.popoverTitle,
        content: this.props.popoverContent,
        container: this.props.container || "body",
      });
    }
  }

  componentWillUnmount() {
    // Clean up the popover to avoid memory leaks
    if (this.popoverRef.current) {
      $(this.popoverRef.current).popover("dispose");
    }
  }

  render() {
    // Attach the ref to your target element
    return (
      <div ref={this.popoverRef} {...this.props}>
        {this.props.children}
      </div>
    );
  }
}

Solution 2: Initialize the ref in the constructor

If you prefer to handle initialization in the constructor, that works too:

export class Popover extends PureComponent<PopoverProps, object> {
  private popoverRef: React.RefObject<HTMLElement>;

  constructor(props: PopoverProps) {
    super(props);
    // Initialize ref inside the constructor
    this.popoverRef = React.createRef<HTMLElement>();
  }

  // ... rest of your component code
}

Solution 3: Use the definite assignment assertion (!)

If you’re absolutely certain the ref will be attached before it’s used (e.g., your render method always creates the element with the ref), you can use the ! operator to tell TypeScript the property will be initialized later:

export class Popover extends PureComponent<PopoverProps, object> {
  // The ! tells TypeScript this will be initialized before use
  private popoverRef!: React.RefObject<HTMLElement>;

  componentDidMount() {
    // Still safe to check if current exists to avoid runtime errors
    if (this.popoverRef.current) {
      $(this.popoverRef.current).popover({ /* your options */ });
    }
  }

  render() {
    return <div ref={this.popoverRef} {...this.props}>{this.props.children}</div>;
  }
}

Key Notes

  • Always check if popoverRef.current is not null or undefined before accessing it—even if you use the definite assignment assertion. This prevents runtime errors if the ref isn’t attached for some reason.
  • Don’t forget to clean up the Bootstrap popover in componentWillUnmount to avoid memory leaks.

内容的提问来源于stack exchange,提问作者Shorn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:16:10