Heim > Artikel > Web-Frontend > Warum muss die Reaktion dies binden?
Der Grund, warum React dies binden muss: Das Binden von Ereignis-Listenern an Komponenten besteht darin, auf Benutzerinteraktionen zu reagieren. Wenn eine bestimmte interaktive Aktion ein Ereignis auslöst, muss die Listening-Funktion häufig den Wert eines bestimmten Zustands der Komponente bedienen Geben Sie dann Antwort-Feedback zum Klickverhalten des Benutzers
Die Betriebsumgebung dieses Tutorials: Windows 7-System, React 17-Version, DELL G3-Computer.
Empfohlen: React-Video-Tutorial
Der Grund, warum React dies binden muss:
1. Details zur Codeausführung
Beim Aufrufen oder Verwenden von ReactDOM.render( )
-Methode generiert beim Rendern an die Schnittstelle eine Instanz der Komponente, da die Komponente wiederverwendet werden kann und objektorientierte Programmierung für ihre Positionierung sehr gut geeignet ist. Gemäß den hierin dargelegten Grundregeln können wir wissen, dass dies hier letztendlich auf die Instanz der Komponente verweist. ReactDOM.render()
方法将其渲染到界面上时会生成一个组件的实例,因为组件是可以复用的,面向对象的编程方式非常适合它的定位。根据this指向的基本规则就可以知道,这里的this最终会指向组件的实例。
组件实例生成的时候,构造器constructor会被执行,此处着重分析一下下面这行代码:
this.handleClick = this.handleClick.bind(this);
此时的this指向新生成的实例,那么赋值语句右侧的表达式先查找this.handleClick( )
这个方法,由对象的属性查找机制(沿原型链由近及远查找)可知此处会查找到原型方法this.handleClick( )
,接着执行bind(this)
,此处的this指向新生成的实例,所以赋值语句右侧的表达式计算完成后,会生成一个指定了this的新方法,接着执行赋值操作,将新生成的函数赋值给实例的handleClick属性,由对象的赋值机制可知,此处的handleClick
会直接作为实例属性生成。总结一下,上面的语句做了一件这样的事情:
把原型方法handleClick()
改变为实例方法handleClick()
,并且强制指定这个方法中的this指向当前的实例。
2. ES5的写法中为什么不用bind(this)?
ES5的写法是指使用React.createClass( )
方法来定义组件,React在V16以上的新版本中已经移除了这个API,你可以通过阅读更早版本的源代码看到这个方法的细节。
//旧版本`react`中`createClass`方法片段 if (this.__reactAutoBindMap) { this._bindAutoBindMethods(); }
在老版本的React中,createClass()
的定义中可以看到上面的代码,抛开其他复杂的逻辑,从方法名就可以看出这是一个自动绑定的方法,实际上在这个方法中所完成的,就是对组件中自定义方法的this强制绑定,感兴趣的读者可以自行翻看源码了解细节。
3. 绑定this的必要性
在组件上绑定事件监听器,是为了响应用户的交互动作,特定的交互动作触发事件时,监听函数中往往都需要操作组件某个状态的值,进而对用户的点击行为提供响应反馈,对开发者来说,这个函数触发的时候,就需要能够拿到这个组件专属的状态合集(例如在上面的开关组件ToggleButton例子中,它的内部状态属性state.isToggleOn
的值就标记了这个按钮应该显示ON或者OFF),所以此处强制绑定监听器函数的this指向当前实例的也很容易理解。
React构造方法中的bind会将响应函数与这个组件Component
进行绑定以确保在这个处理函数中使用this时可以时刻指向这一组件的实例。
4. 如果不绑定this
如果类定义中没有绑定this的指向,当用户的点击动作触发this.handleClick()
这个方法时,实际上执行的是原型方法,可这样看起来并没有什么影响,如果当前组件的构造器中初始化了state这个属性,那么原型方法执行时,this.state
会直接获取实例的state属性,如果构造其中没有初始化state这个属性(比如React中的UI组件),说明组件没有自身状态,此时即使调用原型方法似乎也没什么影响。
事实上的确是这样,这里的bind(this)
const toggleButton = new ToggleButton();Zu diesem Zeitpunkt zeigt dies auf die neu generierte Instanz und dann auf den Ausdruck auf der rechten Seite Die Zuweisungsanweisung sucht zunächst nach dieser Methode
this.handleClick( )
. Basierend auf dem Attributsuchmechanismus des Objekts (Suche von nah nach fern entlang der Prototypkette) können wir erkennen, dass die Prototypmethode this ist .handleClick( )
wird hier gefunden. Führen Sie dann bind(this)
aus, wobei dies auf die neu generierte Instanz verweist, also nachdem der Ausdruck auf der rechten Seite der Zuweisungsanweisung berechnet wurde , wird eine neue Methode generiert, die dies angibt, und dann wird die Zuweisungsoperation ausgeführt. Weisen Sie die neu generierte Funktion dem handleClick-Attribut der Instanz zu, dem handleClick
wird hier direkt als Instanzattribut generiert. Zusammenfassend bewirkt die obige Anweisung eines: Ändern Sie die Prototypmethode handleClick()
in die Instanzmethode handleClick()
und erzwingen Sie die Spezifikation dieser Methode. Dies zeigt zur aktuellen Instanz. 🎜2. Warum wird bind(this) in der ES5-Schreibmethode nicht verwendet? 🎜🎜🎜Die ES5-Schreibmethode bezieht sich auf die Verwendung der React.createClass( )
-Methode, um Komponenten zu definieren Die neue Version über V16 Diese API wurde entfernt. Sie können die Details dieser Methode sehen, indem Sie den Quellcode früherer Versionen lesen. 🎜import {handleClick} = toggleButton;🎜In der alten Version von React können Sie den obigen Code in der Definition von
createClass()
sehen. Abgesehen von anderer komplexer Logik können Sie am Methodennamen erkennen, dass es sich um eine automatische Bindung handelt .-Methode, was bei dieser Methode tatsächlich geschieht, ist die erzwungene Bindung an die benutzerdefinierte Methode in der Komponente. Interessierte Leser können den Quellcode lesen, um Einzelheiten zu erfahren. 🎜🎜🎜3. Die Notwendigkeit, diese 🎜🎜🎜Ereignis-Listener an Komponenten zu binden, besteht darin, auf Benutzerinteraktionen zu reagieren. Wenn eine bestimmte interaktive Aktion ein Ereignis auslöst, muss die Überwachungsfunktion häufig auf einen bestimmten Zustand der Komponente reagieren , und geben Sie dann Antwort-Feedback zum Klickverhalten des Benutzers. Wenn diese Funktion ausgelöst wird, müssen Entwickler in der Lage sein, die Statussammlung exklusiv für diese Komponente abzurufen (im obigen Beispiel der Schalterkomponente ToggleButton ist es beispielsweise so). intern Der Wert des Statusattributs state.isToggleOn
gibt an, dass die Schaltfläche EIN oder AUS anzeigen soll. Daher ist es leicht zu verstehen, dass diese der obligatorischen Bindungs-Listener-Funktion auf die aktuelle Instanz verweist. 🎜🎜Die Bindung im React-Konstruktor bindet die Antwortfunktion an diese Komponente Komponente
, um sicherzustellen, dass sie bei Verwendung in dieser Handlerfunktion immer auf die Instanz dieser Komponente verweisen kann. 🎜🎜🎜4. Wenn dies nicht gebunden ist🎜🎜🎜Wenn es keinen Sinn macht, dies in der Klassendefinition zu binden, ist dies tatsächlich der Fall, wenn die Klickaktion des Benutzers die Methode this.handleClick()
auslöst ausgeführt Es handelt sich um eine Prototypmethode, die jedoch keine Auswirkungen zu haben scheint. Wenn das Statusattribut im Konstruktor der aktuellen Komponente initialisiert wird, wird this.state
direkt abgerufen, wenn die Prototypmethode ausgeführt wird Wenn das Statusattribut der Instanz nicht in der Konstruktion initialisiert ist (z. B. bei UI-Komponenten in React), bedeutet dies, dass die Komponente zu diesem Zeitpunkt keinen eigenen Status hat keine Wirkung. 🎜🎜Tatsächlich ist dies tatsächlich der Fall. Was bind(this)
hier im Voraus vermeiden möchte, ist das berühmte Problem, dass dieser Zeiger fehlt. 🎜🎜Wenn Sie beispielsweise eine Destrukturierungszuweisung verwenden, um eine bestimmte Attributmethode zu erhalten, besteht das Problem, dass diese bei der Referenzkonvertierung verloren geht: 🎜rrreeerrreee🎜Im obigen Beispiel meldet die durch Destrukturierungszuweisung erhaltene handleClick-Methode bei der Ausführung einen Fehler. Das Innere der Klasse wird gezwungen, im strikten Modus ausgeführt zu werden. Dies verliert hier während der Zuweisung seinen ursprünglichen Zeiger und zeigt zur Laufzeit auf undefiniert, und undefiniert hat keine Attribute. 🎜🎜Eine weitere Einschränkung besteht darin, dass eine nicht daran gebundene Antwortfunktion bei der asynchronen Ausführung Probleme verursachen kann, wenn sie als Rückruffunktion an eine asynchrone Ausführungsmethode übergeben wird. 🎜Wenn es für die Komponenteninstanzmethode keine verbindliche Spezifikation dafür gibt, können Sie die Referenzkonvertierung nicht sicher verwenden oder sie bei der zukünftigen Verwendung nicht als Rückruffunktion übergeben, was für die spätere Verwendung und gemeinsame Entwicklung unpraktisch ist.
5. Zusammenfassung
Dies ist sehr flexibel zu verwenden, aber diese Flexibilität bringt auch viel Verwirrung mit sich. Das bind(this)
besteht darin, die Fehler auf Sprachebene von JavaScript zu verbessern. Dieses Problem tritt bei der Verwendung von JavaScript zur Entwicklung von Plug-Ins und Frameworks auf offensichtlich. Der Grund dafür, dass es sich um einen Fehler auf Sprachebene handelt, liegt darin, dass die Angabe dieses Problems im selben Szenario in Java eher der normalen Denklogik entspricht. Wenn die Bindung jedoch nicht in JavaScript angezeigt wird, ist das Ergebnis der Sprachoperation Die Benennung der Methode ist inkonsistent.
Verwandte kostenlose Lernempfehlungen: Javascript-Video-Tutorial
Das obige ist der detaillierte Inhalt vonWarum muss die Reaktion dies binden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!