React で TypeScript な Component 内の一部のメソッドから他の定義済みのはずのプロパティーや state へのアクセスが undefined になった時に思い出したいメモ
期待動作する例
↓は button をポチると hidden で置いてあるファイルアップロード用の input の click を発火するコンポーネント的な例です。
import React, { Component } from "react"; interface IProps { } interface IState { } export default class FileUploader extends Component<IProps, IState> { // ↓ TypeScript で refs 的なことをしたい場合に増える仕込み private fileUploader:React.RefObject<HTMLInputElement>; constructor(props:IProps) { super(props); // ↓ ref る仕込み this.fileUploader = React.createRef<HTMLInputElement>(); this.state = { my_awesome_value: undefined }; } // ↓こう書くと this.fileUploader など期待動作する // あえて method{} ではなく property = closure な定義方法をしているところが核心です handleClick = (): void => { // 無事 ref れていれば input 要素の click を発火できてファイルオープンダイアログが出てくれるところ this.fileUploader.current?.click(); // note: この handleClick の定義方法の場合は state へのアクセスも期待動作します } render() { // ↓ ref= に仕込み return ( <div> <button onClick={this.handleClick} /> <input type="file" id="file" ref={this.fileUploader} style={{ display: "none" }} /> </div> ); } }
ダメな例
// ↓メソッドの定義方法を一見シンプルなただのよくあるメソッド的に記述すると… // handleClick 自体は button の onClick から呼ばれてくれますが… handleClick() { // ↑このメソッドの定義方法だと↓でfileUploader が undefined で runtime に死ぬ this.fileUploader.current?.click(); // note: この handleClick の定義方法の場合は state へのアクセスも undefined で runtime に死にます }
React/TypeScript初心者にはしばらく何が起きているのか脳内が?で満たされながらの状況調査となりましたがわかってしまえば JavaScript 界隈ではしばしば遭遇する類のトラブルだったようです。