Какая разница между "super()" и "super (props)" в React при использовании классов es6?

Когда важно передать props в super() и почему?

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

Ответ 1

Есть только одна причина, когда нужно передавать 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 за ссылку)

Ответ 2

В этом примере вы расширяете класс 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.

Ответ 3

Когда вы передаете props в super, реквизиты присваиваются this. Взгляните на следующий сценарий:

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

Как всегда, когда вы делаете:

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

Ответ 4

В соответствии с исходным кодом

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

вы должны проходить props каждый раз, когда у вас есть реквизит, и вы не помещаете их в this.props вручную.

Ответ 5

Дан Абрамов написал статью на эту тему:

Почему мы пишем супер (реквизит)?

И суть в том, что полезно иметь привычку передавать его, чтобы избежать этого сценария, что, честно говоря, я не вижу, что это вряд ли произойдет:

// 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 
  }
  // ...
}

Ответ 6

При реализации функции 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, его просто пустой объект.

Ответ 7

Вот скрипка, которую я сделал:jsfiddle.net. Это показывает, что реквизиты назначаются не в конструкторе по умолчанию. Насколько я понимаю, они учтены в методе React.createElement. Следовательно, super(props) следует вызывать только тогда, когда конструктор суперкласса вручную присваивает props - this.props. Если вы просто расширите React.Component, вызов super(props) ничего не сделает с реквизитом. Возможно, это будет изменено в следующих версиях React.

Ответ 8

super() используется для вызова родительского конструктора.

super(props) передаст props родительскому конструктору.

В вашем примере super(props) вызовет конструктор React.Component, передав в качестве аргумента props.

Более подробная информация о super:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super

Ответ 9

Здесь мы не получим это в конструкторе, чтобы он возвращался 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 на экземпляр извне сразу после вызова конструктора.

Ответ 10

Для реагирующей версии 16.6.3 мы используем super (props) для инициализации имени элемента состояния : this.props.name

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