reactjs - from - ¿Cuál es la diferencia entre "super()" y "super(props)" en React cuando se usan clases es6?
reactjs update state (10)
¿Cuándo es importante pasar los
props
a
super()
y por qué?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
Al implementar la función
constructor()
dentro de un componente Reaccionar,
super()
es un requisito.
Tenga en cuenta que su componente
MyComponent
está ampliando o tomando prestada la funcionalidad de la clase base
React.Component
.
Esta clase base tiene su propia función
constructor()
que tiene algún código dentro, para configurar nuestro componente Reaccionar por nosotros.
Cuando definimos una función
constructor()
dentro de nuestra clase
MyComponent
, esencialmente
MyComponent
o reemplazamos la función
constructor()
que está dentro de la clase
React.Component
, pero aún debemos asegurarnos de que todo el código de configuración dentro de este
constructor()
todavía se llama a la función.
Entonces, para asegurarnos de que se
React.Component
la
React.Component
constructor()
React.Component
, llamamos
super(props)
.
super(props)
es una referencia a la función
constructor()
los padres, eso es todo.
Tenemos que agregar
super(props)
cada vez que definimos una función
constructor()
dentro de un componente basado en clases.
Si no lo hacemos, veremos un error que dice que tenemos que llamar a
super(props)
.
La razón completa para definir esta función
constructor()
es inicializar nuestro objeto de estado.
Entonces, para inicializar nuestro objeto de estado, debajo de la súper llamada voy a escribir:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
// React says we have to define render()
render() {
return <div>Hello world</div>;
}
};
Así que hemos definido nuestro método
constructor()
, inicializamos nuestro objeto de estado creando un objeto JavaScript, asignándole una propiedad o un par clave / valor, asignando el resultado de esto a
this.state
.
Ahora, por supuesto, esto es solo un ejemplo aquí, así que realmente no he asignado un par clave / valor al objeto de estado, es solo un objeto vacío.
Aquí está el violín que hice:
jsfiddle.net
.
Muestra que los accesorios no están asignados en el constructor por defecto.
Según tengo entendido, están asignados en el método
React.createElement
.
Por lo tanto,
super(props)
debería llamarse solo cuando el constructor de la superclase asigna manualmente
props
a
this.props
.
Si solo extiende el
React.Component
El
React.Component
llama a
super(props)
no hará nada con los props.
Tal vez se cambiará en las próximas versiones de React.
Aquí no conseguiremos esto en el constructor, por lo que volverá indefinido, pero podremos recuperar esto fuera de la función del constructor
class MyComponent extends React.Component {
constructor() {
console.log(this); // Reference Error i.e return undefined
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Si estamos usando super (), también podemos obtener la variable "this" dentro del constructor
class MyComponent extends React.Component {
constructor() {
super();
console.log(this); // this logged to console
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Entonces, cuando estamos usando super (); podremos buscar esto pero this.props no estará definido en el constructor. Pero aparte del constructor, this.props no volverá indefinido.
Si usamos super (props), también podemos usar el valor this.props dentro del constructor
Si desea usar this.props en el constructor, debe pasar los accesorios a super. De lo contrario, no importa porque React establece .props en la instancia desde el exterior inmediatamente después de llamar al constructor.
Cuando pasas los
props
a
super
, los accesorios se asignan a
this
.
Eche un vistazo al siguiente escenario:
constructor(props) {
super();
console.log(this.props) //undefined
}
Como siempre que lo haces:
constructor(props) {
super(props);
console.log(this.props) //props will get logged.
}
Dan Abramov escribió un artículo sobre este tema:
overreacted.io/why-do-we-write-super-props
Y lo esencial es que es útil tener el hábito de pasarlo para evitar este escenario, que honestamente, no veo que sea poco probable que suceda:
// 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
}
// ...
}
En este ejemplo, está extendiendo la clase
React.Component
, y según la especificación ES2015, un constructor de clases hijo no puede hacer uso de
this
hasta que se haya llamado a
super()
;
Además, los constructores de clase ES2015 tienen que llamar a
super()
si son subclases.
class MyComponent extends React.Component {
constructor() {
console.log(this); // Reference Error
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Por el contrario:
class MyComponent extends React.Component {
constructor() {
super();
console.log(this); // this logged to console
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Más detalles según esta excelente respuesta de desbordamiento de pila
Puede ver ejemplos de componentes creados al extender la clase
React.Component
que no llama a
super()
pero notará que estos no tienen un
constructor
, por lo tanto, no es necesario.
class MyOtherComponent extends React.Component {
render() {
return <div>Hi {this.props.name}</div>;
}
}
Un punto de confusión que he visto de algunos desarrolladores con los que he hablado es que los componentes que no tienen
constructor
y, por lo tanto, no llaman a
super()
ninguna parte, todavía tienen
this.props
disponibles en el método
render()
.
Recuerde que esta regla y esta necesidad de crear un enlace
this
para el
constructor
solo se aplica al
constructor
.
Para la versión de reacción 16.6.3, utilizamos super (props) para inicializar el nombre del elemento de estado : this.props.name
constructor(props){
super(props);
}
state = {
name:this.props.name
//otherwise not defined
};
Según el código fuente
function ReactComponent(props, context) {
this.props = props;
this.context = context;
}
debe pasar
props
cada vez que tenga accesorios y no los coloque en
this.props
manualmente.
Solo hay una razón cuando uno necesita pasar
props
a
super()
:
Cuando quieras acceder a
this.props
en constructor.
Paso:
class MyComponent extends React.Component {
constructor(props) {
super(props)
console.log(this.props)
// -> { icon: ''home'', … }
}
}
No pasa:
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'', … }
}
}
Tenga en cuenta que pasar o no pasar
props
a
super
no
tiene
efecto
en los usos posteriores de
this.props
fuera del
constructor
.
Es decir
render
,
shouldComponentUpdate
, o los controladores de eventos
siempre
tienen acceso a él.
Esto se dice explícitamente en la answer Sophie Alpert a una pregunta similar.
La documentación: Estado y ciclo de vida, Agregar estado local a una clase, punto 2, recomienda:
Los componentes de clase siempre deben llamar al constructor base con
props
.
Sin embargo, no se proporciona ninguna razón. Podemos especular que es por subclases o por compatibilidad futura.
(Gracias @MattBrowne por el enlace)
super()
se usa para llamar al constructor padre.
super(props)
pasaría los
props
al constructor padre.
A partir de su ejemplo,
super(props)
llamaría al constructor
React.Component
pasando
props
como argumento.
Más información sobre
super
:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super