props
をsuper()
に渡すことが重要なのはいつですか、またその理由は何ですか?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
props
をsuper()
に渡す必要があるのは、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', … }
}
}
props
にsuper
を渡しても渡さなくても、constructor
の外でthis.props
を後で使用した場合、 効果なし になります。それはrender
、shouldComponentUpdate
、またはイベントハンドラ always にアクセスできます。
これは、ある問題に対するSophie Alpertの answer で明示的に述べられています。
ドキュメント - ステートとライフサイクル、クラスへのローカルステートの追加、ポイント2 -
クラスコンポーネントは常に
props
で基本コンストラクタを呼び出すべきです。
しかし、理由は示されていません。これはサブクラス化によるものか、将来の互換性によるものと推測できます。
(リンクをありがとう@MattBrowne)
この例では、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
にのみ適用されることを忘れないでください。
props
をsuper
に渡すと、小道具はthis
に割り当てられます。次のシナリオを見てください。
constructor(props) {
super();
console.log(this.props) //undefined
}
あなたがするときいつまで:
constructor(props) {
super(props);
console.log(this.props) //props will get logged.
}
のように ソースコード
function ReactComponent(props, context) {
this.props = props;
this.context = context;
}
小道具があるたびにprops
を渡さなければならず、手動でthis.props
に入れないでください。
super()
は、親コンストラクタを呼び出すために使用されます。
super(props)
はprops
を親コンストラクタに渡します。
あなたの例では、super(props)
は引数としてprops
を渡してReact.Component
コンストラクタを呼び出します。
super
に関するさらに詳しい情報: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
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
}
// ...
}
Reactコンポーネント内にconstructor()
関数を実装する場合、super()
が必要条件です。 MyComponent
コンポーネントはReact.Component
基本クラスから機能を拡張または借用していることに注意してください。
この基本クラスは、私たちのために私たちのReactコンポーネントをセットアップするために、その中にいくつかのコードを持つそれ自身のconstructor()
関数を持ちます。
MyComponent
クラス内でconstructor()
関数を定義すると、基本的にはReact.Component
クラス内のconstructor()
関数をオーバーライドまたは置き換えることになりますが、それでもこのconstructor()
関数内のすべてのセットアップコードが呼び出されるようにする必要があります。
React.Component
のconstructor()
関数が確実に呼び出されるようにするために、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
に割り当てることで、状態オブジェクトを初期化しました。もちろん、これはここでのほんの一例ですので、状態オブジェクトにはキーと値のペアを実際には割り当てていません。これは単に空のオブジェクトです。
これが私が作ったフィドルです: https://jsfiddle.net/beshanoe/zpxbLw4j/1/ 。デフォルトでは、小道具はコンストラクタ内では割り当てられていません。私が理解しているように、それらはメソッドReact.createElement
に割り当てられています。したがって、super(props)
は、スーパークラスのコンストラクタが手動でprops
をthis.props
に代入するときにのみ呼び出されるべきです。 React.Component
を拡張しただけでは、super(props)
を呼び出しても小道具は何もしません。たぶんそれはReactの次のバージョンで変更されるでしょう。
ここではコンストラクタでこれを取得しないので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値も使用できます
コンストラクターでthis.propsを使用したい場合は、propsをsuperに渡す必要があります。それ以外の場合は、Reactがコンストラクタを呼び出した直後に外部からインスタンスに.propsを設定するため、問題にはなりません。
反応バージョン16.6.3では、 super(props) を使用して状態要素を初期化します name:this.props.name
constructor(props){
super(props);
}
state = {
name:this.props.name
//otherwise not defined
};