React가 이를 바인딩해야 하는 이유: 구성 요소에 이벤트 리스너를 바인딩하는 것은 사용자 상호 작용에 응답하기 위한 것입니다. 특정 대화형 작업이 이벤트를 트리거할 때 청취 기능은 구성 요소의 특정 상태 값을 작동해야 하는 경우가 많습니다. 그런 다음 사용자의 클릭 동작에 대한 응답 피드백을 제공합니다.
이 튜토리얼의 운영 환경: Windows 7 시스템, React 17 버전, DELL G3 컴퓨터.
추천: react 동영상 튜토리얼
React가 이것을 바인딩해야 하는 이유:
1. 코드 실행 세부 사항
ReactDOM.render( )
를 호출하거나 사용할 때 > 메서드는 구성 요소를 재사용할 수 있고 객체 지향 프로그래밍이 위치 지정에 매우 적합하기 때문에 구성 요소를 인터페이스에 렌더링할 때 구성 요소의 인스턴스를 생성합니다. 이것이 가리키는 기본 규칙에 따르면, 여기서 이것이 결국 컴포넌트의 인스턴스를 가리킬 것이라는 것을 알 수 있습니다. 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();
this.handleClick( )
을 검색합니다. 객체의 속성 검색 메커니즘(프로토타입 체인을 따라 가까운 곳에서 먼 곳까지 검색)을 기반으로 이 메서드를 사용하면 프로토타입 메서드가 this .handleClick( )
이 여기에 있습니다. 그런 다음 bind(this)
를 실행합니다. 여기서 이것은 새로 생성된 인스턴스를 가리키므로 할당문 오른쪽의 표현식이 계산됩니다. , 이를 지정하는 새 메소드가 생성된 다음 할당 작업이 수행됩니다. 새로 생성된 함수를 개체의 할당 메커니즘인 handleClick</code에 할당합니다. > 여기서는 인스턴스 속성으로 직접 생성됩니다. 요약하면 위 명령문은 한 가지 작업을 수행합니다. <p></p>프로토타입 메서드 <code>handleClick()
를 인스턴스 메서드 handleClick()
으로 변경하고 이 메서드의 지정을 강제합니다. 현재 인스턴스로 이동합니다. 🎜2. ES5 작성 방법에서 왜 바인드(this)가 사용되지 않나요? 🎜🎜🎜ES5 작성 방법은 React가 있는 컴포넌트를 정의하는 데 React.createClass()
를 사용하는 것을 의미합니다. V16 이상의 새 버전에서는 이 API가 제거되었으므로 이전 버전의 소스 코드를 읽으면 이 메소드의 세부사항을 볼 수 있습니다. 🎜import {handleClick} = toggleButton;
createClass()
정의에서 위 코드를 볼 수 있습니다. 다른 복잡한 로직은 제쳐두고 메소드 이름에서 이것이 자동 바인딩임을 알 수 있습니다. . 메소드에서 실제로 수행되는 작업은 구성 요소에서 사용자 정의 메소드를 강제로 바인딩하는 것입니다. 관심 있는 독자는 소스 코드에서 자세한 내용을 확인할 수 있습니다. 🎜🎜🎜3. 바인딩의 필요성 🎜🎜🎜구성 요소에서 이벤트 리스너를 바인딩하는 것은 특정 대화형 작업이 이벤트를 트리거할 때 구성 요소 값의 특정 상태에서 작동해야 하는 경우가 많습니다. 그런 다음 사용자의 클릭 동작에 대한 응답 피드백을 제공합니다. 개발자의 경우 이 기능이 트리거되면 이 구성 요소에 대한 독점적인 상태 컬렉션을 가져올 수 있어야 합니다(예를 들어 위의 스위치 구성 요소 ToggleButton 예에서는 내부 상태 속성 state.isToggleOn
의 값은 버튼이 ON 또는 OFF로 표시되어야 함을 표시하므로 필수 바인딩 리스너 함수 중 이 함수가 현재 인스턴스를 가리킨다는 것을 쉽게 이해할 수 있습니다. 🎜🎜React 생성자의 바인딩은 이 핸들러 함수에서 이를 사용할 때 항상 이 구성 요소의 인스턴스를 가리킬 수 있도록 응답 함수를 이 구성 요소 Component
에 바인딩합니다. 🎜🎜🎜4. 바인딩되지 않은 경우🎜🎜🎜클래스 정의에 바인딩할 지점이 없으면 사용자의 클릭 동작이 this.handleClick()
메서드를 트리거할 때 실제로는 실행 프로토타입 메서드이지만 영향은 없는 것 같습니다. 현재 구성 요소의 생성자에서 상태 속성을 초기화한 다음 프로토타입 메서드가 실행되면 this.state
가 직접 가져옵니다. 인스턴스의 상태 속성이 구성에서 초기화되지 않은 경우(예: React의 UI 구성 요소)는 이때 프로토타입 메서드를 호출해도 해당 구성 요소에 자체 상태가 없는 것으로 보입니다. 효과가 없습니다. 🎜🎜사실 이것이 사실입니다. 여기서 bind(this)
가 사전에 피하고 싶은 것은 이 포인터가 누락되는 유명한 문제입니다. 🎜🎜예를 들어 특정 속성 메서드를 얻기 위해 구조 분해 할당을 사용하면 참조 변환에서 이를 잃는 문제가 발생합니다. 🎜rrreeerrreee🎜위 예에서 구조 분해 할당으로 얻은 handlerClick 메서드는 실행 시 오류를 보고합니다. Class의 내부는 강제로 엄격 모드에서 실행됩니다. 여기서는 할당 중에 원래 포인터를 잃고 런타임에 정의되지 않은 항목을 가리키며, 정의되지 않은 속성에는 속성이 없습니다. 🎜🎜또 다른 제한 사항은 this에 바인딩되지 않은 응답 함수가 비동기 실행 시 문제를 일으킬 수 있다는 것입니다. 콜백 함수로 비동기 실행 메서드에 전달되는 경우에도 this에 대한 포인터가 손실되어 발생합니다. 🎜컴포넌트 인스턴스 방식에 대한 필수 사양이 없으면 참조 변환을 안전하게 사용할 수 없거나 향후 사용 시 콜백 함수로 전달할 수 없어 후속 사용 및 공동 개발에 불편이 발생합니다.
5. 요약
이것은 사용하기에 매우 유연하지만 이러한 유연성은 많은 혼란을 가져옵니다. bind(this)
이는 JavaScript의 언어 수준 결함을 개선하는 것입니다. 이는 React에서만 필요한 것이 아닙니다. 이 문제는 JavaScript를 사용하여 플러그인 및 프레임워크를 개발할 때 발생합니다. 분명한. 언어 수준의 결함이라고 하는 이유는 Java에서 동일한 시나리오에서 이를 가리키는 것이 JavaScript에서 바인딩이 표시되지 않으면 언어 연산 결과 및 명명이 더 일반적인 사고 논리에 부합하기 때문입니다. 방법의 상황이 일치하지 않습니다.
관련 무료 학습 권장사항: javascript 비디오 튜토리얼
위 내용은 React가 이것을 바인딩해야 하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!