web-dev-qa-db-ja.com

Es6クラスを使うときのReactの "super()"と "super(props)"の違いは何ですか?

propssuper()に渡すことが重要なのはいつですか、またその理由は何ですか?

class MyComponent extends React.Component {
  constructor(props) {
    super(); // or super(props) ?
  }
}
432
Misha Moroshko

propssuper()に渡す必要があるのは、1つの理由だけです。

コンストラクタでthis.propsにアクセスしたいとき。

通過:

class MyComponent extends React.Component {    
    constructor(props) {
        super(props)

        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

合格しない:

class MyComponent extends React.Component {    
    constructor(props) {
        super()

        console.log(this.props)
        // -> undefined

        // Props parameter is still available
        console.log(props)
        // -> { icon: 'home', … }
    }

    render() {
        // No difference outside constructor
        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

propssuperを渡しても渡さなくても、constructorの外でthis.propsを後で使用した場合、 効果なし になります。それはrendershouldComponentUpdate、またはイベントハンドラ always にアクセスできます。

これは、ある問題に対するSophie Alpertの answer で明示的に述べられています。


ドキュメント - ステートとライフサイクル、クラスへのローカルステートの追加、ポイント2 -

クラスコンポーネントは常にpropsで基本コンストラクタを呼び出すべきです。

しかし、理由は示されていません。これはサブクラス化によるものか、将来の互換性によるものと推測できます。

(リンクをありがとう@MattBrowne)

604
Robin Pokorny

この例では、React.Componentクラスを拡張しています。ES2015仕様に従って、super()が呼び出されるまで、子クラスのコンストラクタはthisを利用できません。また、ES2015クラスコンストラクターは、それらがサブクラスである場合はsuper()を呼び出す必要があります。

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

対照的に、

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

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

/より詳細 - この素晴らしいスタックオーバーフローの答え

super()を呼び出さないReact.Componentクラスを拡張することによって作成されたコンポーネントの例を見るかもしれませんが、これらはconstructorを持っていないことに気付くでしょう。

class MyOtherComponent extends React.Component {
  render() {
    return <div>Hi {this.props.name}</div>;
  }
}

私が話してきた何人かの開発者から見た混乱の1つのポイントは、constructorを持たず、したがってどこでもsuper()を呼び出さないコンポーネントはまだrender()メソッドで利用可能なthis.propsを持っているということです。このルールとthisに対するconstructorバインディングを作成する必要があることはconstructorにのみ適用されることを忘れないでください。

49
Dave

propssuperに渡すと、小道具はthisに割り当てられます。次のシナリオを見てください。

constructor(props) {
    super();
    console.log(this.props) //undefined
}

あなたがするときいつまで:

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}
37
Nahush Farkande

のように ソースコード

function ReactComponent(props, context) {
  this.props = props;
  this.context = context;
}

小道具があるたびにpropsを渡さなければならず、手動でthis.propsに入れないでください。

11
zerkms

super()は、親コンストラクタを呼び出すために使用されます。

super(props)propsを親コンストラクタに渡します。

あなたの例では、super(props)は引数としてpropsを渡してReact.Componentコンストラクタを呼び出します。

superに関するさらに詳しい情報: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super

6
kspence

Dan Abramovはこのトピックに関する記事を書きました:

https://overreacted.io/why-do-we-write-super-props/ /

そしてその要旨は、このシナリオを回避するために pass の習慣があると便利だということです。

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(props) {
    super(); // ???? We forgot to pass props
    console.log(props);      // ✅ {}
    console.log(this.props); // ???? undefined 
  }
  // ...
}
5
Alfonso Pérez

Reactコンポーネント内にconstructor()関数を実装する場合、super()が必要条件です。 MyComponentコンポーネントはReact.Component基本クラスから機能を拡張または借用していることに注意してください。

この基本クラスは、私たちのために私たちのReactコンポーネントをセットアップするために、その中にいくつかのコードを持つそれ自身のconstructor()関数を持ちます。

MyComponentクラス内でconstructor()関数を定義すると、基本的にはReact.Componentクラス内のconstructor()関数をオーバーライドまたは置き換えることになりますが、それでもこのconstructor()関数内のすべてのセットアップコードが呼び出されるようにする必要があります。

React.Componentconstructor()関数が確実に呼び出されるようにするために、super(props)を呼び出します。 super(props)は両親のconstructor()関数への参照です、それだけです。

クラスベースのコンポーネント内でsuper(props)関数を定義するたびに、constructor()を追加する必要があります。

そうでなければ、super(props)を呼び出さなければならないというエラーが表示されます。

このconstructor()関数を定義した全体の理由は、状態オブジェクトを初期化することです。

だから私たちの状態オブジェクトを初期化するために、スーパーコールの下に書くつもりです:

class App extends React.Component {
  constructor(props) {
      super(props);

      this.state = {};
   }

  // React says we have to define render()
  render() {
    return <div>Hello world</div>;
  }
};

そのため、constructor()メソッドを定義し、JavaScriptオブジェクトを作成し、それにプロパティまたはキーと値のペアを割り当て、その結果をthis.stateに割り当てることで、状態オブジェクトを初期化しました。もちろん、これはここでのほんの一例ですので、状態オブジェクトにはキーと値のペアを実際には割り当てていません。これは単に空のオブジェクトです。

5
Daniel

これが私が作ったフィドルです: https://jsfiddle.net/beshanoe/zpxbLw4j/1/ 。デフォルトでは、小道具はコンストラクタ内では割り当てられていません。私が理解しているように、それらはメソッドReact.createElementに割り当てられています。したがって、super(props)は、スーパークラスのコンストラクタが手動でpropsthis.propsに代入するときにのみ呼び出されるべきです。 React.Componentを拡張しただけでは、super(props)を呼び出しても小道具は何もしません。たぶんそれはReactの次のバージョンで変更されるでしょう。

4
beshanoe

ここではコンストラクタでこれを取得しないのでundefinedが返されますが、コンストラクタ関数の外側でこれを取得することができます。

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error i.e return undefined
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

Super()を使用している場合は、コンストラクタ内でも "this"変数を取得できます。

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

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

したがって、super()を使用している場合、これをフェッチすることはできますが、this.propsはコンストラクタ内で未定義になります。ただし、コンストラクタ以外では、this.propsはundefinedを返しません。

super(props)を使用する場合は、コンストラクター内でthis.props値も使用できます

Sophie Alpert's Answer

コンストラクターでthis.propsを使用したい場合は、propsをsuperに渡す必要があります。それ以外の場合は、Reactがコンストラクタを呼び出した直後に外部からインスタンスに.propsを設定するため、問題にはなりません。

2
VIKAS KOHLI

反応バージョン16.6.3では、 super(props) を使用して状態要素を初期化します name:this.props.name

constructor(props){
    super(props);        
}
state = {
  name:this.props.name 
    //otherwise not defined
};
1
shubham kapoor