Перейти к содержимому

Super react js что это

  • автор:

React — для чего нужны super() и super(props)

пожалуйста объясните мне подробно разница между super и super(props) и в целом для чего нужен super? я прочитал в одной статье что с помощью super можно применить в конструкторе this.props, можете мне показать простой пример с использованием this.props

Отслеживать
задан 26 дек 2020 в 21:47
187 1 1 серебряный знак 8 8 бронзовых знаков

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

super() вызывает конструктор наследуемого класса.Это необходимо когда вам нужно допустим получить доступ к переменным наследуемого класса.

В React когда вы вызываете super с пропсами тогда весь компонент получает доступ к ним через this.props .

Без super()

class A < constructor() < this.a = 'hello' >> class B extends A < constructor()< console.log(this.a) //будет ошибка >> console.log(new B())

С super()

class A < constructor(props) < this.props = props >> class B extends A < constructor(props) < super(props) console.log(this.props) >> console.log(new B())

Еще про ключевое слово super могу добавить из книги Кайла Симпсона ES6 не только стр. 75

Ключевое слово super , как правило, рассматривается в связи с классами. Но благодаря тому, что в JS понятие класса приравнивается к понятию обьекта с прототипом, ключевое слово super эффективно работает с краткими методами обычных обьектов.

var o1 = < foo()< console.log("o1.foo"); >> var o2 = < foo()< super.foo(); console.log("o2:foo"); >> Object.setPrototypeOf( o2, o1); o2.foo(); // o1: foo // o2: foo

Ключевое слово super допустимо только в сокращенных методах, а не в свойствах регулярных функциональных выражений. Кроме того, оно действительно только в форме super.XXX( для доступа к свойству / методу) и не применяется в форме super() .

Почему мы пишем super(props)?

Подобный синтаксис был запланирован, когда в React 0.13 была добавлена ​​поддержка простых классов в 2015 году. Определение конструктора и вызов super(props) всегда предполагалось как временное решение, пока поля класса не предоставят эргономичную альтернативу.

Но вернемся к этому примеру, используя только функции ES2015:

class Checkbox extends React.Component < constructor(props) < super(props); this.state = < isOn: true >; > // . >

Здесь у вас не избежно должны возникнуть следующие вопросы: Почему мы вызываем super? Можем ли мы не вызывать его? Если нам нужно вызвать его, что произойдет, если мы не передадим props? Есть ли другие аргументы?

В JavaScript super относится к конструктору родительского класса. (В нашем примере это указывает на реализацию React.Component.)

class Checkbox extends React.Component < constructor(props) < // Нельзя использовать `this` здесь super(props); // А вот здесь можно this.state = < isOn: true >; > // . >

Есть веская причина, по которой JavaScript принудительно вызывает родительский конструктор до того, как вы используете this в нем. Рассмотрим иерархию классов:

class Person < constructor(name) < this.name = name; >> class PolitePerson extends Person < constructor(name) < this.greetColleagues(); // Это запрещено, читайте ниже, почему super(name); >greetColleagues() < alert('Good morning folks!'); >>

Представьте, что вы использовали this до того, как был разрешен вызов super. Месяц спустя мы могли бы изменить welcomeColleagues, чтобы включить имя человека в сообщение:

 greetColleagues()

Но мы забыли, что this.greetColleagues() вызывается до того, как вызов super() смог установить this.name. Так что this.name еще даже не определено! Как видите, такой код может быть очень трудным для размышления.

Чтобы избежать таких ловушек, JavaScript требует, чтобы, если вы хотите использовать this в конструкторе, вы должны сначала вызвать super. Пусть родитель делает свое дело! И это ограничение распространяется и на компоненты React, определенные как классы:

 constructor(props) < super(props); // Теперь можно использовать this здесь this.state = < isOn: true >; >

Но это оставляет нас с другим вопросом: зачем передавать props?

Вы можете подумать, что передача props в super необходима, чтобы базовый конструктор React.Component мог инициализировать this.props:

Действительно, так оно и есть. Это то что он делает.

Но каким-то образом, даже если вы вызовете super() без аргумента props, вы все равно сможете получить доступ к this.props в рендеринге и других методах. (Если не верите мне, попробуйте сами!)

Как это работает? Оказывается, React также присваивает props экземпляру сразу после вызова вашего конструктора:

 // Внутри React const instance = new YourComponent(props); instance.props = props;

Таким образом, даже если вы забудете передать props в super(), React все равно установит их сразу после этого. Для этого есть причина.

Когда React добавил поддержку классов, он добавил поддержку не только классов ES6. Цель состояла в том, чтобы поддерживать как можно более широкий спектр абстракций классов. Было неясно, насколько успешными будут ClojureScript, CoffeeScript, ES6, Fable, Scala.js, TypeScript или другие решения для определения компонентов. Таким образом, React намеренно не высказывал мнения о том, требуется ли вызов super() — даже несмотря на то, что классы ES6 требуют этого.

Значит ли это, что вы можете просто написать super() вместо super(props)?

Вероятно, не потому, что это все еще сбивает с толку. Конечно, React позже назначит this.props после вызова вашего конструктора. Но this.props по-прежнему будет undefined между вызовом super и концом вашего конструктора:

// Inside React class Component < constructor(props) < this.props = props; // . >> // Inside your code class Button extends React.Component < constructor(props) < super(); // Мы забыли передать props console.log(props); // <>console.log(this.props); // undefined > // . >

Отладка может быть еще более сложной, если это происходит в каком-то методе, вызываемом из конструктора. Вот почему я рекомендую всегда передавать super(props), даже если это не является строго необходимым:

class Button extends React.Component < constructor(props) < super(props); // Мы передали props console.log(props); // <>console.log(this.props); // <> > // . >

Это гарантирует, что this.props будет установлен еще до выхода из конструктора.

Есть еще один момент, который может заинтересовать давних пользователей React.

Вы могли заметить, что когда вы используете Context API в классах (либо с устаревшими contextTypes, либо с современным contextType API, добавленным в React 16.6), контекст передается в качестве второго аргумента конструктору.

Так почему бы нам вместо этого не написать super(props, context)? Ну мы конечно же могли бы, но контекст используется редко, так что эта ловушка не так часто всплывает.

С предложением о полях классов вся эта ловушка в основном исчезает. Без явного конструктора все аргументы передаются автоматически. Именно это позволяет такому выражению, как state = <>, при необходимости включать ссылки на this.props или this.context.

С хуками у нас даже нет super или this. Но в прочем это уже совсем другая история…

React

Создавать интерактивные пользовательские интерфейсы на React — приятно и просто. Вам достаточно описать, как части интерфейса приложения выглядят в разных состояниях. React будет своевременно их обновлять, когда данные изменяются.

Декларативные представления сделают код более предсказуемым и упростят отладку.

Основан на компонентах

Создавайте инкапсулированные компоненты с собственным состоянием, а затем объединяйте их в сложные пользовательские интерфейсы.

Поскольку логика компонента написана на JavaScript, а не содержится в шаблонах, можно с лёгкостью передавать самые разные данные по всему приложению и держать состояние вне DOM.

Научитесь однажды — пишите где угодно

Нам не нужно ничего знать про остальную часть вашего технологического стека, поэтому вы можете разрабатывать новую функциональность на React, не изменяя существующий код.

React также может работать на сервере, используя Node.js и на мобильных платформах, используя React Native.

Простой компонент

React-компоненты реализуют метод render() , который принимает входные данные и возвращает что-то для вывода. В этом примере используется XML-подобный синтаксис под названием JSX. Входные данные, передаваемые в компонент, доступны в render() через this.props .

JSX необязателен для работы с React. Попробуйте Babel REPL, чтобы увидеть JavaScript-код, полученный на этапе компиляции JSX.

Загрузка примера с кодом.

Компонент с состоянием

Помимо входных данных (доступных через this.props ), компонент поддерживает внутренние данные состояния (доступные через this.state ). Когда данные состояния компонента изменятся, React ещё раз вызовет render() и обновит отрендеренную разметку.

Загрузка примера с кодом.

Приложение

Используя props и state , можно создать небольшое приложение списка дел. В этом примере используется state для отслеживания текущего списка элементов, а также текста, введённого пользователем. Хотя обработчики событий встроены в разметку, они собираются и реализуются с помощью делегирования событий.

Загрузка примера с кодом.

Компонент с использованием внешних плагинов

React позволяет работать с другими библиотеками и фреймворками. В этом примере используется внешняя библиотека remarkable, чтобы в режиме реального времени преобразовать Markdown-синтаксис, введённый в элемент .

super

Ключевое слово super используется для вызова функций, принадлежащих родителю объекта.

Выражения super.prop и super[expr] действительны в любом определении метода в классах и в литералах объекта.

Синтаксис

super([arguments]); // вызов родительского конструктора. super.functionOnParent([arguments]); 

Описание

В конструкторе ключевое слово super() используется как функция, вызывающая родительский конструктор. Её необходимо вызвать до первого обращения к ключевому слову this в теле конструктора. Ключевое слово super также может быть использовано для вызова функций родительского объекта.

Пример

Использование super в классах

Этот фрагмент кода взят из classes sample (демонстрация). В этом примере super() вызывается, чтобы не повторять части конструктора, одинаковые для классов Rectangle и Square .

class Rectangle  constructor(height, width)  this.name = "Rectangle"; this.height = height; this.width = width; > sayName()  console.log("Hi, I am a ", this.name + "."); > get area()  return this.height * this.width; > set area(value)  this._area = value; > > class Square extends Rectangle  constructor(length)  this.height; // ReferenceError, super должен быть вызван первым! // Здесь вызывается конструктор родительского класса с длинами, // указанными для ширины и высоты класса Rectangle super(length, length); // Примечание: в производных классах super() необходимо вызывать, прежде чем // использовать 'this'. Если этого не сделать, произойдет ошибка ReferenceError. this.name = "Square"; > > 

Вызов статических методов через super

Вы также можете вызывать super для статических методов.

class Rectangle  static logNbSides()  return "У меня 4 стороны"; > > class Square extends Rectangle  static logDescription()  return super.logNbSides() + ", равные между собой"; > > Square.logDescription(); // 'У меня 4 стороны, равные между собой' 

Удаление свойств через super вызывает ошибку

Вы не можете использовать оператор delete и super.prop или super[expr] для удаления свойств родительского класса, он выдаст: ReferenceError .

class Base  constructor() > foo() > > class Derived extends Base  constructor() > delete()  delete super.foo; // это плохо > > new Derived().delete(); // ReferenceError: invalid delete involving 'super'. 

super.prop не может переопределять свойства, защищённые от записи

При определении незаписываемых свойств с помощью, например, Object.defineProperty , super не может перезаписать значение свойства.

class X  constructor()  Object.defineProperty(this, "prop",  configurable: true, writable: false, value: 1, >); > > class Y extends X  constructor()  super(); > foo()  super.prop = 2; // Невозможно перезаписать значение. > > var y = new Y(); y.foo(); // TypeError: "prop" доступен только для чтения console.log(y.prop); // 1 

Использование super.prop в объектных литералах

Super также можно использовать в объекте инициализатора / литерала. В этом примере метод определяют два объекта. Во втором объекте super вызывает метод первого объекта. Это работает благодаря Object.setPrototypeOf() , с помощью которого мы можем установить прототип для obj2 в obj1 , так что super может найти method1 в obj1 .

var obj1 =  method1()  console.log("method 1"); >, >; var obj2 =  method2()  super.method1(); >, >; Object.setPrototypeOf(obj2, obj1); obj2.method2(); // выведет "method 1" 

Спецификации

Specification
ECMAScript Language Specification
# sec-super-keyword

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 6 янв. 2024 г. by MDN contributors.

Your blueprint for a better internet.

MDN

Support

  • Product help
  • Report an issue

Our communities

Developers

  • Web Technologies
  • Learn Web Development
  • MDN Plus
  • Hacks Blog
  • Website Privacy Notice
  • Cookies
  • Legal
  • Community Participation Guidelines

Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2024 by individual mozilla.org contributors. Content available under a Creative Commons license.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *