Sintaxis de la clase Javascript y vincular esto en métodos [duplicado]

Dec 09 2020

Quería entender la diferencia básica entre cómo funciona la siguiente sintaxis.

// 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>

Mientras que la sintaxis 1 necesita que se especifique un enlace explícito dentro del constructor. Sin embargo, parece que con la sintaxis 2, eso no es necesario. ¿Cómo puede la sintaxis 2 lograr el enlace automáticamente?

Supongo que esta comprensión / sintaxis se puede extender para cualquier marco, incluidos React, Angular, Ember, etc.

Respuestas

1 CertainPerformance Dec 09 2020 at 11:52

Los campos de clase, es decir, las propiedades definidas directamente dentro del cuerpo de la clase, son esencialmente solo azúcar de sintaxis para lo mismo dentro del constructor. Así que esto:

class Something {
  handleClick = () => {
    console.log('this is:', this)
  }
}

es, desazucarado:

class Something {
  constructor() {
    this.handleClick = () => {
      console.log('this is:', this)
    };
  }
}

Con el azúcar eliminado, debe quedar claro lo que está sucediendo: la función de flecha significa que se thisrefiere a lo que thisestá en el constructor, que es la instancia en sí, no se necesita vinculación.

Esto no es solo una cuestión de React o framework, estas son reglas estándar en JavaScript vanilla.

Si no vincula el método o usa una función de flecha o algo por el estilo, entonces:

<button onClick={this.handleClick}>

falla por la misma razón que

someButton.addEventListener('click', myObj.someFn)

también fallará al llamar someFncon un contexto de llamada de myObj- todo lo que el navegador sabe es llamar a la devolución de llamada pasada al oyente del clic; el contexto de llamada de myObjse pierde cuando se pasa así.