Sintaxe da classe Javascript e vinculando-a a métodos [duplicado]
Eu queria entender a diferença básica entre como funciona a sintaxe abaixo.
// Syntax 1
class Component extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
// ...
}
}
// Syntax 2
handleClick = () => {
console.log('this is:', this)
}
<button onClick={this.handleClick}>
{'Click me'}
</button>
Enquanto a sintaxe 1 precisa de uma ligação explícita a ser especificada dentro do construtor. No entanto, parece que com a sintaxe 2, isso não é necessário. Como a sintaxe 2 consegue realizar a vinculação automaticamente?
Presumo que este entendimento / sintaxe pode ser estendido para qualquer estrutura, incluindo React, Angular, Ember, etc
Respostas
Os campos de classe - ou seja, propriedades definidas diretamente dentro do corpo da classe - são essencialmente apenas açúcar de sintaxe para a mesma coisa dentro do construtor. Então, é isso:
class Something {
handleClick = () => {
console.log('this is:', this)
}
}
é, desugared:
class Something {
constructor() {
this.handleClick = () => {
console.log('this is:', this)
};
}
}
Com a adição de açúcar removida, deve ficar claro o que está acontecendo - a função de seta significa que this
se refere ao que this
está no construtor, que é a própria instância, sem a necessidade de vinculação.
Isso não é apenas uma coisa do React ou do framework - essas são regras padrão no JavaScript vanilla.
Se você não vincular o método ou usar uma função de seta ou algo parecido, então:
<button onClick={this.handleClick}>
falha pela mesma razão que
someButton.addEventListener('click', myObj.someFn)
também falhará ao chamar someFn
com um contexto de chamada de myObj
- tudo que o navegador sabe é chamar o retorno de chamada passado para o ouvinte de clique; o contexto de chamada de myObj
se perde quando passado assim.