Varför är det nödvändigt att använda binda på händelsen lyssnare av komponenter?

varför är det nödvändigt att använda binda på händelsen lyssnare av komponenter?

Med lite att du har arbetat med att Reagera säker på att du kommer att ha var tvungen att ta för att genomföra en viss händelse lyssnaren i ett av dina komponenter, som till exempel att hantera klicka på en knapp för att:

klass AwesomeComponent sträcker sig Reagera.Komponent{
konstruktör( rekvisita ){
super( rekvisita );
denna.onClick = detta.onClick.bind ();
}
onClick(event){
// ...
den }
render(){
return (
< - knappen type="button"
onClick={detta.onClick}>
Klicka på
</ - knappen>
);
}
}

Ett vanligt misstag när man arbetar med evenemanget lyssnare inom komponenten är inte bindear komponentens funktion, så att när händelsen utlöses vi får felmeddelandet:

inte kan läsa egendom "..." för odefinierade

Hur fungerar detta i Javascript?

I allmänhet, det sätt på vilket den rörliga är bunden inom en funktion beror på det sätt på vilket denna funktion anropas. På detta sätt, det är å ena sidan vad som är känt som standard bindning i är bunden till den globala objekt där det körs Javascript (eller odefinieradi de fall som vi är i strikt läge) och detta är det sätt på vilket du binder – om ingen regel matchar:

function foo(){
- konsolen.log(this); // "detta" är den globala objekt
}
foo();

å andra sidan, det är också den implicita bindning, där är bundna till det objekt som anropas metoden:

var obj = {
namn: Gerard',
foo: function() {
- konsolen.logga in(det här.namn); // 'denna' poäng till obj
}
};
obj.foo(); // Gerardo

På detta sätt, när funktionen fooutförs är bunden till rörlig objekt , så att vad vi får i konsolen är fastigheten namnobjekt.

men detta betyder inte att - kommer alltid att peka på adv - inom funktionen foo. I följande exempel:

var namn = "meeeec";
var otherFoo = obj.foo;
otherFoo(); // meeeec

resultatet är meeeec, det vill säga fastigheten namni den globala objekt, i stället för objekt adv - om, eller odefinieradför att köra Javascript i strikt läge).

Detta händer också när vi arbetar med återuppringning av händelsen lyssnare eller någon annan funktion som du genomför. Till exempel, när vi använder den funktionen setTimeout :

funktionen setTimeout(återuppringning, delay){
 //vänta 'försening' millisekunder
 återuppringning();
}
setTimeout( obj.foo, 1000 );

Internt, Javascript är att göra följande steg:

callback = obj.foo;

så att, som i föregående exempel, när du kör callback-funktion, funktionen foo - har förlorat sitt sammanhang och därmed är bunden till den globala objekt (eller odefinierad ).

sätt att lösa detta är att ta till den metoden bind(explicit hårt bindande), som är att säga, att tvinga javascript för att den rörliga - tar som ett värde argumentet skickas.

var namn = "meeeec";
var otherFoo = obj.foo.bind(obj);
otherFoo(); // Gerardo

I detta fall måste variabeln i sig är en referens till object adv - så att du får ut värdet på din fastighet namn .

summera

gå Tillbaka till början av artikeln, när vi arbetar med komponenter av att Reagera och händelse lyssnare, det är en mycket liknande situation som den vi har kommenterat i fråga om standard bindande. När vi passerar hänvisning till den funktion som ansvarar för att hantera händelsen som en callback:

< - knappen type="button" onClick={detta.onClick}>Klicka på Mig</ - knappen>

funktionen förlorar sitt sammanhang så att när det körs, variabeln inte längre refererar till objektet klass som innehåller metod, men det tar på värdet odefinierad .

Ett förenklat exempel på vad som händer är följande:

class Foo {
konstruktör(namn){
detta.namn = namn
}
 aMethod() {
- konsolen.logga in(det här.namn);
}
}
var foo = new X('Gerardo');
foo.aMethod(); // Gerardo
// " Om vi tilldelar den metod foo till en annan variabel
// och köra det, vi får fel:
var myEventListener = foo.aMethod;
myEventListener(); // TypeError: detta är odefinierat

Observera: kroppen av klasser i Javascript alltid är igång i strikt läge, orsaken som vi får fel och att inte få tillgång till det globala objektet.

det Är av denna anledning som vi anropa metoden bind (vanligtvis i konstruktorn av funktionen i sig) när vi vill undvika detta fel:

class Foo {
konstruktör(namn){
detta.namn = namn;
denna.aMethod = detta.aMethod.bind ();
}
 aMethod(){
- konsolen.logga in(det här.namn);
}
}
var foo = new X('Gerardo');
foo.aMethod(); // Gerardo
var display = foo.aMethod;
display(); // Gerardo

We will be happy to hear your thoughts

Leave a reply