¿Por qué y cuándo necesitamos vincular funciones y controladores de eventos en React?

Resuelto kukrt asked hace 7 años • 2 respuestas
class SomeClass extends Component{
  someEventHandler(event){
  }
  render(){
    return <input onChange={------here------}>
  }
}

Veo diferentes versiones de ------here------la parte.

// 1
return <input onChange={this.someEventHandler.bind(this)}>

// 2
return <input onChange={(event) => { this.someEventHandler(event) }>

// 3
return <input onChange={this.someEventHandler}>

¿En qué se diferencian las versiones? ¿O es sólo una cuestión de preferencia?


Gracias a todos por las respuestas y comentarios. Todos son útiles y recomiendo encarecidamente leer este enlace PRIMERO si está confundido como yo acerca de esto.
http://blog.andrewray.me/react-es6-autobinding-and-createclass/

kukrt avatar Dec 13 '16 11:12 kukrt
Aceptado

El enlace no es algo específico de React, sino más bien cómo thisfunciona en Javascript. Cada función/bloque tiene su propio contexto, ya que las funciones son más específicas en cuanto a cómo se llaman. El equipo de React tomó la decisión de thisno vincularse a los métodos personalizados de la clase (es decir, no a los métodos integrados como componentDidMount), al agregar compatibilidad con ES6 (sintaxis de clase).

Cuándo debe vincular el contexto depende del propósito de las funciones; si necesita acceder a accesorios, estado u otros miembros de la clase, entonces deberá vincularlo.

Para su ejemplo, cada uno es diferente y depende de cómo esté configurado su componente.

Pre vinculante a tu clase.

.bind(this)se utiliza para vincular este contexto a la función de sus componentes. Sin embargo, devuelve una nueva referencia de función en cada ciclo de renderizado. Si no desea vincular cada uso de la función (como en un controlador de clics), puede vincular previamente la función.

a. en tu constructor haz el enlace. alias

class SomeClass extends Component{
    constructor(){
        super();
        this.someEventHandler = this.someEventHandler.bind(this);
    }
    someEventHandler(event){
    }
    ....
} 

b. cree sus funciones personalizadas en las funciones de flecha gruesa de clase. alias

class SomeClass extends Component{
    someEventHandler = (event) => {
    }
    ....
}

Enlace de tiempo de ejecución a su clase

Algunas formas comunes de hacer esto.

a. puede envolver la función de controlador de componentes con una función lambda (flecha gruesa) en línea.

onChange={ (event) => this.someEventHandler(event) }

esto puede proporcionar funcionalidad adicional, como si necesita pasar datos adicionales para el controlador de clics <input onChange={(event) => { this.someEventHandler(event, 'username') }>. Lo mismo se puede hacer conbind

b. Puedes utilizarlo .bind(this)como se describe arriba.

onChange={ this.someEventHandler.bind(this) }

con parámetros adicionales<input onChange={ this.someEventHandler.bind(this, 'username') }>

Si desea evitar la creación de una nueva referencia de función pero aún necesita pasar un parámetro, es mejor abstraerlo a un componente secundario. Puedes leer mas al respecto aquí

en tus ejemplos

// 1
return <input onChange={this.someEventHandler.bind(this)}>

Esto es solo hacer un enlace del controlador de eventos en tiempo de ejecución a su clase.

// 2
return <input onChange={(event) => this.someEventHandler(event) }>

Otro enlace de tiempo de ejecución a su clase.

// 3
return <input onChange={this.someEventHandler}>

Simplemente está pasando la función como función de devolución de llamada para que se active cuando ocurre el evento de clic, sin parámetros adicionales. ¡Asegúrate de previncularlo!

Para resumir. Es bueno pensar en cómo optimizar tu código, cada método tiene una utilidad/propósito dependiendo de lo que necesites.

John Ruddell avatar Dec 13 '2016 04:12 John Ruddell

¿Por qué vincular una función de React?

Cuando define un componente usando una clase ES6, un patrón común es que un controlador de eventos sea un método en la clase. En JavaScript, los métodos de clase no están vinculados de forma predeterminada. Si lo olvida bind this.someEventHandlery lo pasa a onChange, quedará indefinido cuando realmente se llame a la función.

Generalmente, si hace referencia a un método sin ()después, como onChange={this.someEventHandler}, debe vincular ese método.

Hay tres formas de vincular su onChangefunción al contexto correcto

Primero

return <input onChange={this.someEventHandler.bind(this)}>

En este utilizamos bindexplícitamente la función para que el evento onChange esté disponible como argumento para eventHandler. También podemos enviar algún otro parámetro con tipo de sintaxis como

return <input onChange={this.someEventHandler.bind(this, state.value)}>

Segundo

return <input onChange={(event) => { this.someEventHandler(event) }>

Esta es una sintaxis de ES6, mediante la cual podemos especificar los parámetros que queremos pasar a la someEventHandlerfunción. Sin embargo, esto es equivalente .bind(this). También nos da la flexibilidad de enviar otros atributos junto con el evento como

return <input onChange={(event, value) => { this.someEventHandler(event, value) }>

Tercero

Defina la función someEventHandler usando la función Flecha

someEventHandler = () => {
    console.log(this); // now this refers to context of React component
}

An arrow functionno tiene su propio this, thisse utiliza el valor del contexto de ejecución adjunto y, por lo tanto, la función anterior obtiene el contexto correcto.

o vincularlo en el constructor como

constructor(props) {
   super(props);
   this.someEventHandler = this.someEventHandler.bind(this);
}


return <input onChange={this.someEventHandler}>

En este método, el evento se adjunta directamente a la someEventHandlerfunción. No se pueden pasar otros parámetros de esta manera.

Shubham Khatri avatar Dec 13 '2016 04:12 Shubham Khatri