Quando é que é importante passar props
para super()
, e por quê?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
Quando é que é importante passar props
para super()
, e por quê?
class MyComponent extends React.Component {
constructor(props) {
super(); // or super(props) ?
}
}
Respostas:
Há apenas um motivo para passar props
para super()
:
Quando você deseja acessar this.props
no construtor.
Passagem:
class MyComponent extends React.Component {
constructor(props) {
super(props)
console.log(this.props)
// -> { icon: 'home', … }
}
}
Não passando:
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', … }
}
}
Note que passar ou não passar props
a super
tem nenhum efeito sobre os usos posteriores do this.props
lado de fora constructor
. Ou seja render
, os shouldComponentUpdate
manipuladores de eventos sempre têm acesso a ele.
Isso é explicitamente dito na resposta de Sophie Alpert a uma pergunta semelhante.
A documentação - Estado e Ciclo de Vida, Adicionando Estado Local a uma Classe, ponto 2 - recomenda:
Os componentes de classe sempre devem chamar o construtor base com
props
.
No entanto, nenhum motivo é fornecido. Podemos especular que seja por causa de subclassificação ou por compatibilidade futura.
(Obrigado @MattBrowne pelo link)
this.props
é, a undefined
menos que seja passado para super()
. De qualquer forma, não afeta a renderização ou a disponibilidade posterior this.props
da render()
função.
super
, você tem referência a eles no construtor.
props
para super()
: facebook.github.io/react/docs/... . Não sei por que, já que, como você menciona, this.props
é acessível de outros métodos de qualquer maneira ... talvez eles estejam recomendando isso para compatibilidade futura, caso versões futuras do React possam querer fazer algo com props
o construtor?
props
para super
quando, como você apontou, o props
parâmetro está disponível para uso no construtor e this.props
funciona em qualquer outro lugar? Existe algum benefício em usar this.props
apenas props
? É uma má prática desestruturar props
o construtor? Acho que ainda estou deixando de ver um caso quando você já tinha precisa passar props
para super
, mas eu estou disposto a apostar que é apenas a minha ignorância, ha.
super(props)
, poderá chamar métodos que usam this.props
do construtor , como this.doStuffUsingThisDotProps()
, sem ter que passar o parâmetro props para esses métodos / funções. Acabei de escrever um construtor fazendo isso, o que aparentemente exigiria que eu o usasse super(props)
primeiro, de acordo com as respostas a esta pergunta.
Neste exemplo, você está estendendo a React.Component
classe e, de acordo com a especificação do ES2015, um construtor de classe filho não pode usar this
até super()
que seja chamado; Além disso, os construtores de classe do ES2015 precisam chamar super()
se forem subclasses.
class MyComponent extends React.Component {
constructor() {
console.log(this); // Reference Error
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Por contraste:
class MyComponent extends React.Component {
constructor() {
super();
console.log(this); // this logged to console
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Mais detalhes de acordo com esta excelente resposta de estouro de pilha
Você pode ver exemplos de componentes criados estendendo a React.Component
classe que não chama, super()
mas notará que estes não possuem um constructor
, portanto, por que não é necessário.
class MyOtherComponent extends React.Component {
render() {
return <div>Hi {this.props.name}</div>;
}
}
Um ponto de confusão que vi de alguns desenvolvedores com quem conversei é que os componentes que não possuem constructor
e, portanto, não chamam em super()
lugar algum, ainda estão this.props
disponíveis no render()
método. Lembre-se de que esta regra e essa necessidade de criar uma this
ligação para o constructor
único se aplicam ao constructor
.
super()
e super(props)
).
Quando você passa props
para super
, os objetos são atribuídos this
. Dê uma olhada no seguinte cenário:
constructor(props) {
super();
console.log(this.props) //undefined
}
No entanto, quando você faz:
constructor(props) {
super(props);
console.log(this.props) //props will get logged.
}
Conforme código fonte
function ReactComponent(props, context) {
this.props = props;
this.context = context;
}
você deve passar props
toda vez que tiver adereços e não os colocar this.props
manualmente.
super(props)
e a outra não. Mas seus consumidores definem adereços. Qual é a diferença?
this.props = props
e super(props)
é a mesma coisa?
this.props
partir de 'fora' - independentemente do que é feito no construtor.
Dan Abramov escreveu um artigo sobre este tópico:
Por que escrevemos super (adereços)?
E a essência disso é que é útil ter o hábito de contorná- lo para evitar esse cenário. Honestamente, não acho improvável que isso aconteça:
// 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()
é usado para chamar o construtor pai.
super(props)
passaria props
para o construtor pai.
Do seu exemplo, super(props)
chamaria o React.Component
construtor de passagem props
como argumento.
Mais informações em super
:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super
Ao implementar a constructor()
função dentro de um componente React, super()
é um requisito. Lembre-se de que seu MyComponent
componente está estendendo ou emprestando funcionalidades da React.Component
classe base.
Essa classe base tem uma constructor()
função própria que possui algum código para configurar nosso componente React para nós.
Quando definimos uma constructor()
função dentro de nossa MyComponent
classe, estamos essencialmente substituindo ou substituindo a constructor()
função que está dentro da React.Component
classe, mas ainda precisamos garantir que todo o código de instalação dentro dessa constructor()
função ainda seja chamado.
Assim, para garantir que o React.Component
's constructor()
função é chamada, chamamos super(props)
. super(props)
é uma referência à constructor()
função dos pais , isso é tudo.
Temos que adicionar super(props)
sempre que definirmos uma constructor()
função dentro de um componente baseado em classe.
Caso contrário, veremos um erro dizendo que temos que ligar super(props)
.
A razão inteira para definir essa função constructor()
é inicializar nosso objeto de estado.
Então, para inicializar nosso objeto de estado, sob a super chamada, vou escrever:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
// React says we have to define render()
render() {
return <div>Hello world</div>;
}
};
Assim, definimos nosso constructor()
método, inicializamos nosso objeto de estado criando um objeto JavaScript, atribuindo uma propriedade ou um par de chave / valor a ele, atribuindo o resultado disso a this.state
. Agora é claro que este é apenas um exemplo aqui, então eu realmente não atribuí um par de chave / valor ao objeto de estado, é apenas um objeto vazio.
Aqui está o violino que eu fiz: jsfiddle.net . Mostra que os adereços não estão atribuídos no construtor por padrão. Pelo que entendi, eles são avaliados no método React.createElement
. Assim super(props)
deve ser chamado somente quando assings construtor manualmente da superclasse props
para this.props
. Se você apenas estender a React.Component
chamada super(props)
, nada fará com adereços. Talvez isso seja alterado nas próximas versões do React.
Aqui não conseguiremos isso no construtor, portanto ele retornará indefinido, mas poderemos buscá-lo fora da função do construtor
class MyComponent extends React.Component {
constructor() {
console.log(this); // Reference Error i.e return undefined
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Se estivermos usando super (), também podemos buscar a variável "this" dentro do construtor
class MyComponent extends React.Component {
constructor() {
super();
console.log(this); // this logged to console
}
render() {
return <div>Hello {this.props.name}</div>;
}
}
Então, quando estamos usando super (); seremos capazes de buscar isso, mas this.props será indefinido no construtor. Mas, além do construtor, this.props não retornará indefinido.
Se usarmos super (props), poderemos usar o valor this.props também dentro do construtor
Se você quiser usar this.props no construtor, precisará passar props para super. Caso contrário, isso não importa, porque o React define .props na instância de fora imediatamente após chamar o construtor.
Para a versão 16.6.3 do react, usamos super (props) para inicializar o nome do elemento de estado : this.props.name
constructor(props){
super(props);
}
state = {
name:this.props.name
//otherwise not defined
};