Когда важно перейти 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.Components 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
};