import React from "react";
class App extends React.Component {
// 상태값 num 선언
state = {
num: 0
};
// 버튼을 누르면 this.state.num을 1만큼 증가시킴
increase() {
this.setState(current => ({ num: current.num + 1 }));
console.log("increase메서드의 this는", this);
}
render() {
return (
<div>
<h1>Class Component this</h1>
<h2>{this.state.num}</h2>
{/* 클릭 이벤트 핸들러의 콜백으로 컴포넌트 메서드 전달 */}
<button onClick={this.increase}>증가</button>
</div>
);
}
}
export default App;
해당 increase 메소드는 this가 undefined로 this.setState를 하려 할때 오류가 발생한다.
class App {
constructor(state){
this.state = state
}
showState(){
console.log(this.state);
}
}
const app = new App('num');
app.showState(); // num
const showState = app.showState;
showState(); // TypeError: Cannot read property 'state' of undefined
해당 부분을 보면 컴포넌트 메소드가 다른 변수에 할당되어 따로 호출되는 것을 통해 문제가 발생한다.
즉, 정리하자면 우리가 만든 메서드들을 각 태그들의 이벤트로 등록하게 되는 과정에서 각 메서드와 컴포넌트 인스턴스의 관계가 끊겨버리기 때문
(위와같은 무언가 그러한 과정이 존재하기 때문이다.)
- bind()
- 화살표 함수
render() {
return (
<div>
<h1>Class Component this</h1>
<h2>{this.state.num}</h2>
{/* 기존 increase메소드에 render()의 this인 App을 바인딩함 */}
{/* this를 명시적으로 작성해줬기 때문에 this를 잃어버릴 일이 없음 */}
<button onClick={this.increase.bind(this)}>증가</button>
</div>
);
}
increase에 대해서 this를 명시적으로 해당 컴포넌트로 나타내준다.
render() {
return (
<div>
<h1>Class Component this</h1>
<h2>{this.state.num}</h2>
{/* 컴포넌트 메소드 앞에 붙는 요 this는 App을 가리킨다*/}
<button onClick={() => this.increase()}>증가</button>
</div>
);
}
항상 상위 스코프의 this에 바인딩