Soy nuevo en React y estoy un poco confundido aquí
export default class Message extends Component { m1() { console.log("Hello world"); } render() { return ( <button className="btn btn-primary" onClick={this.m1}>Click 1</button> ); } }¿Por qué el valor de esto no es el elemento del botón en sí?
¿Por qué se refiere al objeto llamador?
valor de this dentro del eventHandler en el componente basado en clase
Como se describe en la documentación aquí , React no hace nada para establecer this en un valor específico, por lo que si hace onClick={myFunction} , es equivalente a llamar a myFunction(event) . En JavaScript, llamar a una función de esa manera usa el valor predeterminado this , que no está undefined en modo estricto (el código class siempre es estricto). Esto es diferente de cómo funciona addEventListener , donde el sistema de eventos DOM establece this en el elemento al que se adjunta el controlador de eventos al llamar a la función.
¿Por qué el valor de esto no es el elemento del botón en sí?
Una elección de diseño del equipo de React. Si desea el elemento al que se adjuntó el controlador de eventos, puede obtenerlo del objeto de evento que se pasa a su controlador usando event.currentTarget (esto también es cierto con los controladores addEventHandler en código que no es React; this y event.currentTarget tienen el mismo valor por defecto).
¿Por qué se refiere al objeto llamador?
no lo hace Si quiere decir cómo puede hacer que se refiera a la instancia del componente de clase, consulte las respuestas de esta pregunta . Las soluciones habituales son usar bind en la función del controlador de eventos, o usar una función de flecha contenedora (más en las respuestas de esta pregunta ).
Por ejemplo, con respecto a su código, puede vincular m1 en su constructor:
export default class Message extends Component { constructor(props) { // *** super(props); // *** this.m1 = this.m1.bind(this); // *** } // *** m1() { console.log("Hello world"); } render() { return ( <button className="btn btn-primary" onClick={this.m1}>Click 1</button> ); } }O bien, puede hacer una función de flecha de envoltura donde la llame:
return ( <button className="btn btn-primary" onClick={(event) => this.m1(event)}>Click 1</button> {/* −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^^^ */} );O bien, algunas personas asignan una función de flecha a un campo de clase en lugar de usar la sintaxis del método:
export default class Message extends Component { m1 = () => { // *** console.log("Hello world"); // *** }; // *** render() { return ( <button className="btn btn-primary" onClick={this.m1}>Click 1</button> ); } }No soy partidario de eso porque significa que el método no está en el prototipo, lo cual es útil por varias razones (incluida la burla para las pruebas), pero es una opción.
onClick={this.m1}
El valor entre { y } es una expresión que se evalúa cuando se llama a la función que está dentro ( render() en este caso).
Entonces, el valor de this desde el alcance de render() y depende de cómo se llama render() (aparte de las excepciones para bind , funciones de flecha, etc.).
En este caso, el resultado de la expresión es la función m1 que se asigna a la propiedad onClick del componente de button .
Esto es diferente del atributo onclick de HTML que acepta una cadena que representa el cuerpo de una función que se evalúa cuando se activa el evento del cliente .