React의this 지향 설명

6376 단어 Reactthis가리키다
일기장부는 일반적으로React에서this가 가리키는 문제를 세어 보려고 합니다. 구체적인 절차는 사건의 세 가지 요소: 원인, 경과, 결과에 따릅니다.하하하하!

원인:


모두가 알다시피React의 디자인은 응답식이다. 사용자가 DOM을 조작하지 않고 데이터를 조작하면 페이지가 업데이트된다.
데이터가 바뀌면 업데이트됩니다. 모든 DOM을 업데이트하는 건가요?물론 아니야, 변한 대로 다시 렌더링해.그러면 데이터 변경 전후의 DOM을 비교해야 합니다.리얼 덤을 직접 비교해볼까요?이렇게 하면 성능이 매우 낮을 것이다. React는 가상 DOM을 비교하고 가상 DOM도 대상이다. 단지 실제 DOM에 비해 많은 속성이 적고 더욱 가볍다.
가상 DOM은 어떻게 쓰나요?원생 JS 우리는 문서를 사용할 수 있습니다.createElement() 메서드, 노드를 생성합니다.React에서도 React를 사용할 수 있습니다.create Element(component,props,children). 하지만 이런 글쓰기는 여러 겹의 끼워넣기를 만나면 눈이 어지럽습니다.그래서 JSX는 "횡공출세"를 했고 JSX는 사실, React였다.create Element의 문법 설탕은 우리가 사용하기에 더욱 편리하다. 직접적으로

hello

이런 형식으로 쓸 수 있다.
그런데 또 문제가 생겼어요!JSX 문법은 웹팩에 인식되지 않습니다. 웹팩은 기본적으로 처리만 가능합니다.js 접두사 이름의 파일입니다. 그래서 Babel이라는 자바스크립트 컴파일러를 빌려야 합니다. 그리고 babel은 엄격한 모드를 열었습니다**

import React, { Component } from 'react'

export default class index extends Component {
    // speak(){
    //     console.log(this)// undefined
    // }
    speak = () => console.log(this)// 
    render() {
        return (
            <div>
                <button onClick={this.speak}> </button>
            </div>
        )
    }
}
this는 본질적으로 그 호출자를 가리키는 것이다.this는 함수가 실행될 때 귀속되고 JS의 일반 함수는 모두 윈도우즈에서 호출되기 때문에 윈도우즈를 가리키며 엄격한 모드를 연 다음에undefined이다.

(function(){
    console.log(this)//window
})()
JSX에서 전달되는 이벤트는 하나의 문자열(원생 JS에서 감청 이벤트, 리셋 함수 형식을 사용하고 Vue에서 감청 이벤트에 전달되는 것은 문자열 변수)이 아니라 하나의 함수(예를 들어 위: onClick={this.speak})이다. 이때 onClick은 중간 변수이고 최종적으로React에서 이 함수를 호출한다. 엄격한 모드가 켜졌기 때문에this는undefined이다.그래서 처리 함수의this 지향은 잃어버릴 수 있습니다.

경과:


사실 우리가 필요로 하는 것은this가 현재의 실례화 대상을 가리키는 것이다. 의심할 여지없이 코드 작성을 많이 편리하게 할 것이다.클래스 구성 요소 안에 두 군데가 있는this는 현재 실례화된 대상을 가리킨다.

1. 구조 함수


클래스 구성 요소 안의 구조기 안의this는 실례 대상을 가리키는데 이것은 ES6 클래스의 특성입니다.
아시다시피 Javascript에는 C++, JAVA의 클래스 개념이 없고 ES6 클래스의 실현도 원형 체인을 바탕으로 이루어진 것입니다.
ES6 이전에 객체를 인스턴스화하려면 다음과 같이 해야 합니다.

function Animal(name, age) {
  this.name = name
  this.age = age
}
Animal.prototype.say = function () {
  console.log(this.name)
}
const Dog = new Animal('dog', 3)
Dog.say()  // dog
그 중의 new 연산자는 먼저 빈 대상 {}을 생성한 다음에this 바늘을 생성하여this 바늘을 이 빈 대상을 가리킨다.구조 함수를 실행할 때, {}에 해당한다.name=dog,{}.age=3 마찬가지로 이 대상의 동적 속성을 추가합니다.마지막으로 이 생성된 대상을 Dog에게 주고,
우리가 ES6의class를 사용하여 위의 클래스를 설명하면 코드는 다음과 같다.

class Animal {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  say() {
    console.log(this.name)
  }
}
const Dog = new Animal('dog', 3)
Dog.say()  // dog
클래스 구현과 위쪽은 큰 차이가 없어야 하기 때문에this는 실례 대상을 가리킨다.

2.render 함수


render 함수 안에 있는this도 실례를 가리킨다.왜?
우선render 방법은 클래스 구성 요소의 원형 위에 있습니다. React는 구성 요소가 클래스 정의를 사용하는 것을 발견할 때 뒤에 new가 이 클래스의 실례를 나타냅니다. 이 실례는React가 new를 도와줍니다. 그 다음에 실례는render 방법을 호출하여 가상 DOM을 실제 DOM으로 변환합니다. 그래서render의this는 실례를 가리키는 것입니다. 왜냐하면 그가 호출한 것이기 때문입니다.유사한 것은,render는 하나의 생명주기 갈고리이고, 다른 생명주기 갈고리 안의this도 실례 구성 요소를 가리킨다.

3.bind 및 화살표 함수


this 문제를 해결하려면 두 개의 지식 저장이 있어야 한다
(1)bind
callapplybind는 함수 원형 위에 정의되어 있습니다. 함수this의 방향을 바꾸는 데 사용됩니다. 전송된 첫 번째 매개 변수는this입니다. 뒤에 있는 매개 변수는fun1의 매개 변수입니다.
차이점:
  • call과bind가 호출된 함수는 여러 개의 apply를 전달할 수 있고 매개 변수를 한 그룹에 넣는다
  • call과 apply는 즉시 실행 함수를 되돌려주고,bind는 새로운 함수를 되돌려주고,bind()()도 즉시 실행
  • bind를 사용하여this를 연결한 후 이 함수 안에 있는this는 누가 호출하든지 변경할 수 없습니다
  • 
    let aa = {
        fun1: function(a,b){
            console.log(this)
            console.log(a-b);
        }
    }        
    let bb = {
        fun2: function(a,b){
            console.log(this)
            console.log(a+b);
        }
    }
    
    aa.fun1.call(bb,11,22);//bb-11
    bb.fun2.apply(aa,[11,22]);//aa 33
    aa.fun1.bind(bb,11,22)();//bb -11
    
    (2) 화살표 함수
    화살표 함수: 화살표 함수는 자신의 실행 상하문을 만들지 않기 때문에 화살표 함수 중의this는 모두 외부의this로 외부 작용 영역에서this의 정의가 있을 때까지this를 층층이 찾습니다
    
    const A = {
        arrow:() =>{
            console.log(this)//window
        },
        func:function(){
            this.arrow()//window
            console.log(this)//A
            setTimeout(() => {
                console.log(this)//A
            });
        }
    }
    A.arrow()
    A.func()
    

    결과:


    해결 방법은 내가 알아서 할게, 헤헤!

    방법1: 구조 함수에bind 사용하기

    
    import React, { Component } from 'react'
    
    export default class index extends Component {
        constructor(){
            super()
            this.speak = this.speak.bind(this)
            /* this :this.speak = this.speak.bind(this), this ,
           fnc , bind this , 
           , fnc*/
        }
        speak(){
            console.log(this)// 
        }
        render() {
            return (
                <div>
                    <button onClick={this.speak}> </button>
                </div>
            )
        }
    }
    

    방법2: 화살표 함수를 클래스에 지정하는 속성

    
    import React, { Component } from 'react'
    
    export default class index extends Component {
        speak = () =>{
            console.log(this)
        }
        render() {
            return (
                <div>
                    <button onClick={this.speak}> </button>
                </div>
            )
        }
    }// , 
    

    참고: 성능 차이


    화살표 함수를 사용하면 성능이 비교적 낮을 수 있습니다. 화살표 함수는 방법이 아니라 익명 함수 표현식이기 때문에 클래스에 추가하는 유일한 방법은 속성에 값을 부여하는 것입니다.앞에서 ES6의 클래스를 소개했을 때 알 수 있듯이 ES 클래스는 완전히 다른 방식으로 처리하는 방법과 속성을 가지고 있다
    방법은 모든 실례가 한 번 정의하는 것이 아니라 클래스의 원형에 추가됩니다.
    클래스 속성 문법은 같은 속성을 모든 실례에 분배하는 문법 설탕으로 실제로는constructor에서 이렇게 실현된다.
    
        constructor(){
            super()
            this.speak = () => {console.log(this)}
        }
    
    이것은 새로운 실례가 생성될 때 함수가 재정의되고 JS 실례 공유 원형 방법의 장점을 잃게 된다는 것을 의미한다.방법1, 단지 실례를 생성할 때bind 조작을 한 걸음 더 했을 뿐 효율과 메모리 점용에 있어 큰 장점을 가진다
    이상은 React의this지향에 대한 상세한 내용입니다. React의this지향에 대한 더 많은 자료는 저희 다른 관련 글에 주목하세요!

    좋은 웹페이지 즐겨찾기