this, 바인딩

이상혁·2023년 11월 23일
0

Front-End

목록 보기
11/11
post-thumbnail

⚡️ this란?

  • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-reference variable)이다.
  • 함수 내부에서 인자를 지역 변수처럼 사용할 수 있는 것처럼, this도 지역 변수처럼 사용할 수 있다.
  • 단, this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.
  • this는 함수가 호출되는 시점의 실행 컨텍스트(Execution Context)이다.
  • 함수를 실행하는 환경(호출하는 방법, 환경)이 달라지면 this도 변한다

자바스크립트에서 this = ‘누가 나를 불렀냐’ , 선언이 아닌 호출에 따라 달라짐

// 개발자도구에서 그냥 this를 찍었을때
// 그냥 호출하면 global object를 가리킴
// 브라우저에서 호출할 경우 object Window
> this
> Window{어쩌구 저쩌구}

var x = this;
console.log(x); // Window

function h() {
	console.log(this);
}
h(); // Window
//똑같이 그냥 window임
//window = 모든 전역변수, 함수, DOM 보관 및 관리하는 전역객체

var obj1 = {
  data : 'Kim',
  hamsu : function(){ console.log('간지') } 
}

obj1.hamsu();
// 콘솔 = '간지'

var obj1 = {
  data : 'Kim',
  hamsu : function(){ console.log(this) } 
}

obj1.hamsu(); //{ data : 'Kim', 간지함수 : f }
// 메소드안에 this를 사용할 경우 this = 메소드를 가지고 있는 오브젝트 뜻함

var obj2 = {
  data : {
    hamsu : function(){ console.log(this) }
  }
}

obj2.data.hamsu(); // obj2.data === this 
// 메소드를 담고있는 주인

✅ 정리 ✅ 
// JavaScript Function안에 this?
1. 현재 함수를 부른 객체가 누구인지 나타낸다

// 일반 함수 호출 에서 this?
const name = 'Hyuk';
function hello(thing){
 // 전역에서 호출되서 여기서 this = [object Window]호출
 console.log(this + 'says hello ' + thing); // [object Window] say hello world
 console.log('My name is' + this.name); // My name is Hyuk
}
// 호출 시 함수 매개변수 thing에 'world'가 전달됨
hello('world');
1. 글로벌 객체인 window 객체

// 객체 메소드에서 this?
let person = {
 name : 'Jake',
 hello : function(thing){
	console.log(this.name + ' says hello ' + thing);
 }
}

person.hello('world'); // Jake says hello world
1. 호출한 객체 

const value = 100;
  const myObj = {
    value: 1,
    func1: function() {
      console.log(`func1's this.value: ${this.value}`);

      const func2 = function() {
        console.log(`func2's this.value ${this.value}`);
      };
      func2();
    }
  };

    myObj.func1();
1. func1의 경우 객체의 메서드라 1이 출력됨.
2. func2의 경우에는 일반 함수 호출이기 때문에 100이 출력됨

// 생성자 함수
new 키워드 이용한 생성자 함수 호출

const Person = function(name) {
  console.log(this);  //Person 생성된 객체
  this.name = name; //객체에 name 속성 추가
};

// 새로운 객체 생성 , 'foo'라는 객체
const foo = new Person("foo"); // Person 
// 객체가 새로 생성될때 'foo'라는 객체에 name 속성값으로 'foo'가 할당됨
console.log(foo.name); // foo

🌟 바인딩이란?

바인딩은 컴포넌트의 상태(state)나 속성(props)을 이벤트 핸들러 또는 id 매핑을 통해 데이터를 반영하거나 동적으로 수정하기 위한 기술이다. (연결시켜준다고 이해하면됨 value 값을 넘겨주는건 아님)

  1. 이벤트 바인딩
    1. click or change 등 처리 시 this 키워드 사용하여 컴포넌트의 상태나 속성에 접근할때 this가 컴포넌트를 올바르게 참조하는 것이 이벤트 바인딩이다
  2. 데이터 바인딩
    1. React에서 컴포넌트 상태(id같은) UI 요소에 연결하는 것. 이 바인딩을 통해 상태나 속성의 변경이 자동으로 반영되도록 하는 것이 데이터 바인딩이다

JavaScript Binding

var obj = {
	prop : 'Hello',
	sayHello : function() {
		console.log( this.prop);
	}
};

obj.sayHello(); // 'hello'
// sayHello 메서드안의 this = obj 객체가 되어서 obj.prop인 Hello가 찍힘

var ref = obj.sayHello;
ref(); //undefined

// 변수 ref에 담길때 obj와의 관계 상실이 됨
// 이럴 때 필요한게 '바인딩'

var ref = obj.sayHello.bind(obj);
ref(); //'Hello'
// 전달할 때 obj까지 바인딩시켜서 보내면됨

React Binding

// 상태 초기값 설정
const [color, setColor] = useState('white');

//상태 변경 함수
function changeColor() {
	// 상태를 'black'으로 변경
  setColor('black');
}
//onClick 이벤트에 changeColor 함수를 바인딩하여 클릭 시 실행되도록 함
  onClick={changeColor}
// style 속성에 바인딩을 통해 동적으로 배경색을 상태에 맞게 설정
  style={{ backgroundColor: color }}
<button onClick={changeColor} style={{ backgroundColor: color }}>변경해보세요</button>

// 이벤트 바인딩: onClick 이벤트에 changeColor 함수를 할당하여 클릭 이벤트가 발생할 때 이 함수가 실행되도록 합니다. 
// 이때 this 키워드가 사용되지 않고, 대신 함수 내에서 정의된 setColor 함수를 호출하여 컴포넌트의 상태를 업데이트합니다.

// 데이터 바인딩: style 속성에 객체를 전달하여 동적으로 배경색을 설정합니다. 
// 이 객체의 backgroundColor 속성에는 상태 값인 color를 바인딩하여 상태가 변경될 때마다 UI가 자동으로 업데이트되도록 합니다.

리액트에서 바인드 에러 예시

class EventBind extends Component {
  constructor(props) {
    super(props)

    this.state = {
      message: 'Hello'
    }
  }

  handleClick() {
    this.setState({
      message: 'Goodbye!' // 클릭하면 Goodbye 바뀌는 함수 
    })
  }

  render() {
    return (
      <div>
        <div>{this.state.message}</div>
        <button onClick={this.handleClick}>Click</button>
      </div> // 온클릭 이벤트와 함수 연결 
    )
  }
}

1. 초기 설정 key: message , value : Hello
2. handleClick 호출될때 message value 를 GoodBye 로 변경
3. 버튼 클릭시 나오는 에러 => Cannot read property 'setState' of undefined
4. 버튼에 있는 this.handleClick = 독립적으로 호출되서 전역 객체인 window를 가리키기 때문에 에러가 나오게됨

// 해결방법
// handleClick.bind 사용하여 바인딩해줌
1.  constructor(props) {
    super(props);
    this.state = {
      message: 'Hello'
    };
    this.handleClick = this.handleClick.bind(this);
  }
// 화살표 함수사용시 자동으로 바인딩됨
2.  handleClick = () => {
    this.setState({
      message: 'Goodbye!'
    });
  };

바인드 에러 해결 방법

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
	// handleClick.bind가 없을경우 Undefined 
    
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}> // 연결
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

0개의 댓글