ウェブサイト検索

reactjs - カスタムの React TypeScript 要素を HTMLElement にキャストする方法は?


カスタム要素の配列があり、それぞれの要素にrefを保存して、特定のものに対してfocus()を呼び出したいと考えています。カスタムReact要素をDOM要素にキャストしてfocus()を可能にすることは可能でしょうか?

SampleFeed.tsx

class Feed extends React.Component<{ posts: Post[] },{}> {
    private postRefs: Map<number, Post> = new Map<number, Post>();

    render() {
      <div>
         {this.props.posts.map(
          ((post: Post), (index: number)) =>
           <Post
            ref={(element: Post) => this.postRefs.set(index, element)}
            post={post}
          />)
         }
      </div>
    }

    focusTargetElement() {
      // Does not compile, "Property focus does not exist on Post"
      this.postRefs.get(5).focus();
    }
}

回答 #1

Postコンポーネントのソースコードを投稿していないので、入力をレンダリングするサンプルの子コンポーネントを使用します

オプション1:

子コンポーネントに要素の参照を保存し、親コンポーネントから呼び出される public な focus() メソッドを作成する

class Post extends React.PureComponent {

  private ref: HTMLInputElement

  public render() {
    return <input ref={(ref) => this.ref = ref}/>
  }

  public focus() {
    this.ref.focus()
  }

}

https://codesandbox.io/s/4w0qrmjk37

オプション2:

コールバックメソッドを子コンポーネントのプロパティに渡す

class Post extends React.PureComponent<{setRef: (ref: HTMLInputElement) => void}> {

  public render() {
    return <input ref={(ref) => this.props.setRef(ref)}/>
  }

}

そして要素の参照を親に保持する

class Feed extends React.Component<{ posts: Post[] },{}> {
    private postRefs: Map<number, HTMLInputElement> = new Map<number, HTMLInputElement>();

    render() {
      <div>
         {this.props.posts.map(
          ((post: Post), (index: number)) =>
           <Post
            setRef={(element: HTMLInputElement) => this.postRefs.set(index, element)}
            post={post}
          />)
         }
      </div>
    }

    focusTargetElement() {
      // Does not compile, "Property focus does not exist on Post"
      this.postRefs.get(5).focus();
    }
}

サンドボックス: https://codesandbox.io/s/v3o954jvyl