C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

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 界隈ではしばしば遭遇する類のトラブルだったようです。

参考