Когда важно перейти 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
в конструкторе.
Передача:
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 за ссылку)
this.props
это undefined
если не передается super()
. В любом случае, это не влияет позже рендеринга или наличие this.props
в render()
функции.
super
, у вас есть ссылка на них в конструкторе.
props
по адресуsuper()
: facebook.github.io/react/docs/… . Я не уверен, почему, так как, как вы указываете, this.props
доступен в других методах в любом случае ... возможно, они рекомендуют это для будущей совместимости в случае, если будущие версии React могут захотеть что-то сделать props
в конструкторе?
props
к super
когда, как вы указали, то props
параметр прямо доступен для нас , чтобы использовать в конструкторе , и this.props
работает везде? Есть ли польза от использования this.props
над просто props
? Это плохая практика для деструктурировать props
в конструкторе? Я думаю , что я до сих пор не в состоянии увидеть случай , когда вы когда - либо необходимо пройти , props
чтобы super
, но я готов поспорить , что это только мое невежество, ха.
super(props)
, вы можете вызывать методы, которые используют this.props
в конструкторе from , например this.doStuffUsingThisDotProps()
, без необходимости передавать параметр props этим методам / функциям. Я просто написал конструктор, делающий это, что, по-видимому, потребовало бы, чтобы я super(props)
сначала использовал его , в соответствии с ответами на этот вопрос.
В этом примере вы расширяете 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
.
super()
и super(props)
).
Когда вы переходите 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(props)
а другой нет. Но их потребители устанавливают реквизит. В чем разница?
this.props = props
и super(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
}
// ...
}
super()
используется для вызова родительского конструктора.
super(props)
будет переходить props
к родительскому конструктору.
Из вашего примера, super(props)
вызовет React.Component
конструктор, передавая в props
качестве аргумента.
Дополнительная информация по адресуsuper
:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
При реализации constructor()
функции внутри компонента React, super()
это требование. Имейте в виду, что ваш MyComponent
компонент расширяет или заимствует функциональность из React.Component
базового класса.
Этот базовый класс имеет собственную constructor()
функцию, в которой есть некоторый код для настройки нашего компонента React для нас.
Когда мы определяем constructor()
функцию внутри нашего MyComponent
класса, мы, по сути, переопределяем или заменяем constructor()
функцию, которая находится внутри React.Component
класса, но нам все еще нужно убедиться, что весь установочный код внутри этой constructor()
функции по-прежнему вызывается.
Чтобы убедиться, что функция React.Component
s 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
. Теперь, конечно, это только пример, поэтому я на самом деле не назначил пару ключ / значение для объекта состояния, это просто пустой объект.
Вот скрипка, которую я сделал: jsfiddle.net . Это показывает, что реквизиты назначаются не в конструкторе по умолчанию. Как я понимаю, они заданы в методе 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 в конструкторе, вам нужно передать реквизиты super. В противном случае это не имеет значения, потому что React устанавливает .props для экземпляра извне сразу после вызова конструктора.
Для реагирующей версии 16.6.3 мы используем super ( props ) для инициализации имени элемента состояния : this.props.name
constructor(props){
super(props);
}
state = {
name:this.props.name
//otherwise not defined
};