Когда важно передать props в super() и почему?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
Когда важно передать props в super() и почему?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
Есть только одна причина, когда нужно передавать props в super():
Когда вы хотите получить доступ к this.props в конструкторе.
Passing:
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 не влияет на последующее использование this.props вне constructor. То есть, render, shouldComponentUpdate или обработчики событий всегда имеют к нему доступ.
Об этом прямо говорится в одном ответе Софи Альперт на аналогичный вопрос.
Документация - Состояние и жизненный цикл, Добавление локального состояния в класс, пункт 2 - рекомендует:
Компоненты класса всегда должны вызывать базовый конструктор с
props.
Однако причина не указана. Мы можем предположить, что это либо из-за подклассов, либо для будущей совместимости.
(Спасибо @MattBrowne за ссылку)
В этом примере вы расширяете класс React.Component и по спецификации ES2015, конструктор дочернего класса не может использовать this пока не будет вызван вызов super(); Кроме того, конструкторы классов 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>;
}
}
Более подробно в соответствии с этим отличным ответом на переполнение стека
Вы можете увидеть примеры компонентов, созданных путем расширения класса React.Component который не вызывает super() но вы заметите, что у них нет constructor, поэтому он не нужен.
class MyOtherComponent extends React.Component {
render() {
return <div>Hi {this.props.name}</div>;
}
}
Одна из проблем, которые я видел у некоторых разработчиков, с которыми я говорил, заключается в том, что компоненты, которые не имеют constructor и поэтому не называют super() нигде, все еще имеют this.props доступные в методе render(). Помните, что это правило и необходимость создания 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 вручную.
Дан Абрамов написал статью на эту тему:
Почему мы пишем супер (реквизит)?
И суть в том, что полезно иметь привычку передавать его, чтобы избежать этого сценария, что, честно говоря, я не вижу, что это вряд ли произойдет:
// 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
}
// ...
}
При реализации функции constructor() внутри компонента React требуется требование super(). Имейте в виду, что ваш компонент MyComponent расширяет или заимствует функциональность из базового класса React.Component.
Этот базовый класс имеет собственную constructor() функцию, которая имеет внутри нее некоторый код, чтобы настроить наш компонент React для нас.
Когда мы определяем функцию constructor() внутри нашего класса MyComponent, мы по существу переопределяем или заменяем функцию constructor() которая находится внутри класса React.Component, но нам все равно нужно убедиться, что весь код установки внутри этого constructor() функция все еще вызвана.
Таким образом, чтобы React.Component функцию React.Component constructor(), мы вызываем super(props). super(props) является ссылкой на функцию constructor() родителей constructor(), вот и все.
Мы должны добавлять super(props) каждый раз, когда мы определяем функцию constructor() внутри компонента класса.
Если мы не увидим ошибку, говорящую, что мы должны назвать super(props).
Вся причина для определения этого constructor() funciton заключается в инициализации нашего объекта состояния.
Поэтому, чтобы инициализировать наш объект состояния, под супер-вызовом я собираюсь написать:
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. Теперь, конечно, это просто пример, поэтому я действительно не назначил пару ключ/значение объекту state, его просто пустой объект.
Вот скрипка, которую я сделал:jsfiddle.net. Это показывает, что реквизиты назначаются не в конструкторе по умолчанию. Насколько я понимаю, они учтены в методе React.createElement. Следовательно, super(props) следует вызывать только тогда, когда конструктор суперкласса вручную присваивает props - this.props. Если вы просто расширите React.Component, вызов super(props) ничего не сделает с реквизитом. Возможно, это будет изменено в следующих версиях React.
super() используется для вызова родительского конструктора.
super(props) передаст props родительскому конструктору.
В вашем примере super(props) вызовет конструктор React.Component, передав в качестве аргумента props.
Более подробная информация о super:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
Здесь мы не получим это в конструкторе, чтобы он возвращался 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(), то мы можем также получить "эту" переменную внутри конструктора
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 не будет возвращать неопределенные.
Если мы используем супер (реквизит), то мы можем также использовать значение this.props внутри конструктора
Если вы хотите использовать this.props в конструкторе, вам нужно передать реквизиты супер. В противном случае это не имеет значения, поскольку React устанавливает.props на экземпляр извне сразу после вызова конструктора.
Для реагирующей версии 16.6.3 мы используем super (props) для инициализации имени элемента состояния : this.props.name
constructor(props){
super(props);
}
state = {
name:this.props.name
//otherwise not defined
};