mokajima.com

なぜ super() に props を渡すのか

はじめに

React の component は関数として定義することがほとんどになりました。しかしながら、React Hooks 登場以前のプロダクトを扱う場合、React.Component を継承したサブクラスとして component を定義しているケースも多いかと思います。

React.Component を継承したサブクラスとして component を定義する場合、以下のようなコードを書いていました。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    // do something
  }
}

何度も書いてきたコードです。しかし、よくよく思い返してみると、あまり深く考えずに super()props を渡してしまっていたことに気が付きました。そこで super()props を渡すことでどのような処理が行われるのかを調べてみることにしました。

super()

JavaScript のクラス構文において、サブクラスの constructor() での super() の呼び出しは、継承する親クラスの constructor() を呼び出します。これによりサブクラスの constructor() 内での this へのアクセスが可能となります。

class MyClass extends ParentClass {
  constructor() {
    super();
    // do something
  }
}

super(props)

super() の挙動を踏まえると、以下のコードでは super(props)React.Component クラスの constructor()props を渡していることになります。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    // do something
  }
}

それでは React.Component クラスの constructor() では何をしているのでしょうか。該当のコードは次の通りです。

/**
 * Base class helpers for the updating state of a component.
 */
function Component(props, context, updater) {
  this.props = props;
  this.context = context;
  // If a component has string refs, we will assign a different object later.
  this.refs = emptyObject;
  // We initialize the default updater but the real one gets injected by the
  // renderer.
  this.updater = updater || ReactNoopUpdateQueue;
}

コードを見ると、引数として受け取った propsthis.props に設定していることがわかります。 これにより、React.Component を継承したサブクラスの constructor() では this.props へのアクセスが可能となります。

もし super()props を渡さない場合、this.props へのアクセスを試みると undefined が返されます。

class MyComponent extends React.Component {
  constructor() {
    super()
    console.log(this.props); // undefined
  }
}

参考