¿Cuál es la diferencia entre "super()" y "super(props)" en React cuando se usan clases es6?

Resuelto Misha Moroshko asked hace 9 años • 10 respuestas

¿Cuándo es importante pasar propsa super()y por qué?

class MyComponent extends React.Component {
  constructor(props) {
    super(); // or super(props) ?
  }
}
Misha Moroshko avatar Jun 01 '15 18:06 Misha Moroshko
Aceptado

Sólo hay una razón por la que es necesario pasar propsa super():

Cuando quieras acceder this.propsen constructor.

Paso:

class MyComponent extends React.Component {    
    constructor(props) {
        super(props)

        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

No pasar:

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 propsa no supertiene ningún efecto en usos posteriores de this.propsoutside constructor. Es decir render, shouldComponentUpdateo los controladores de eventos siempre tienen acceso a él.

Esto se dice explícitamente en la respuesta de 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 la clase siempre deben llamar al constructor base con props.

Sin embargo, no se proporciona ningún motivo. Podemos especular que se debe a la subclasificación o a la compatibilidad futura.

(Gracias @MattBrowne por el enlace)

Robin Pokorny avatar Jan 25 '2016 14:01 Robin Pokorny

En este ejemplo, está ampliando la React.Componentclase y, según la especificación ES2015, un constructor de clase secundaria no puede utilizarlo thishasta que super()haya sido llamado; Además, los constructores de clases de ES2015 deben llamar 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

Es posible que vea ejemplos de componentes creados al extender la React.Componentclase que no llaman, super()pero notará que no tienen un constructor, por lo que no es necesario.

class MyOtherComponent extends React.Component {
  render() {
    return <div>Hi {this.props.name}</div>;
  }
}

Un punto de confusión que he visto en algunos desarrolladores con los que he hablado es que los componentes que no tienen constructory, por lo tanto, no llaman super()a ningún lado, todavía están this.propsdisponibles en el render()método. Recuerde que esta regla y esta necesidad de crear un thisenlace para el constructorsolo se aplica al constructor.

Dave avatar Dec 03 '2015 21:12 Dave

Cuando pasas propsa super, los accesorios se asignan a this. Eche un vistazo al siguiente escenario:

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

Como siempre cuando lo haces:

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}
Nahush Farkande avatar Sep 08 '2016 06:09 Nahush Farkande

Al implementar la constructor()función dentro de un componente de React, super()es un requisito. Tenga en cuenta que su MyComponentcomponente está ampliando o tomando prestada funcionalidad de la React.Componentclase base.

Esta clase base tiene una constructor()función propia que tiene algo de código dentro para configurar nuestro componente React por nosotros.

Cuando definimos una constructor()función dentro de nuestra MyComponentclase, esencialmente estamos anulando o reemplazando la constructor()función que está dentro de la React.Componentclase, pero aún debemos asegurarnos de que constructor()se siga llamando a todo el código de configuración dentro de esta función.

Entonces, para asegurarnos de que se llame a la React.Componentfunción constructor(), llamamos a super(props). super(props)es una referencia a la constructor()función de los padres, eso es todo.

Tenemos que agregar super(props)cada vez que definimos una constructor()función dentro de un componente basado en clases.

Si no lo hacemos, veremos un error que indica que tenemos que llamar super(props).

La única razón para definir esta constructor()función es inicializar nuestro objeto de estado.

Entonces, para inicializar nuestro objeto de estado, debajo de la superllamada 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>;
  }
};

Entonces, definimos nuestro constructor()método, inicializamos nuestro objeto de estado creando un objeto JavaScript, asignándole una propiedad o un par clave/valor, asignando el resultado a this.state. Ahora, por supuesto, esto es solo un ejemplo, por lo que en realidad no he asignado un par clave/valor al objeto de estado, es solo un objeto vacío.

Daniel avatar Nov 27 '2018 21:11 Daniel

Dan Abramov escribió un artículo sobre este tema:

¿Por qué escribimos super(props)?

Y lo esencial es que es útil tener el hábito de pasarlo para evitar este escenario, que honestamente no veo improbable 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 
  }
  // ...
}
Alfonso Embid-Desmet avatar Jan 23 '2019 18:01 Alfonso Embid-Desmet