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
