리액트 클래스 컴포넌트를 사용할 경우에는 this를 신경 써서 작성해야 합니다. 생성자(constructor) 함수 안에서 state를 정의할 경우, 자식 컴포넌트로 전달한 props에 접근할 경우, 컴포넌트에서 선언한 메서드를 참조할 경우 등 this를 사용하고 있음을 확인할 수 있습니다. 이번 포스팅에서 클래스 컴포넌트의 이벤트 처리 시 this 바인딩이 어떤 식으로 되고 있는지 알아보겠습니다.
this
javascript의 this는 일반적으로 함수를 호출하는 객체에 대한 참조이다.
(자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수)
함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다.
this는 다음번에 자세히 알아보도록 하겠습니다.
📌 라이프사이클 메서드의 this
라이프사이클 메서드의 this가 어디에 바인딩되는지 확인해 보겠습니다.
class App extends React.Component {
constructor(props) {
super(props);
console.log("constructor", this);
}
componentDidMount() {
console.log("componentDidMount", this);
}
render() {
console.log("render", this);
return (
<div className="App">
class components this
</div>
);
}
}
컴포넌트가 렌더링 되고 콘솔을 확인한 결과입니다.
보시다시피 라이프사이클 메서드의 this 바인딩 결과는 모두 컴포넌트를 가리키고 있습니다. 그렇다면 componentDidMount() 메서드에서 컴포넌트 메서드를 호출하고 이 메서드 또한 this가 컴포넌트를 가리키고 있을까요? componentMethod() 메서드를 추가해 보겠습니다.
...
componentDidMount() {
console.log("componentDidMount", this);
this.componentMethod();
}
componentMethod() {
console.log("componentMethod", this);
}
...
컴포넌트 메서드 또한 this 바인딩 결과를 보면 컴포넌트를 가리키는 것을 확인할 수 있습니다.
📌 이벤트 핸들러 콜백 함수로 등록한 컴포넌트 메서드의 this
위에서 보다시피 컴포넌트 내부에서 선언한 메서드의 this는 컴포넌트가 바인딩되어 있습니다. 그런데 이벤트 핸들러 콜백함수로 등록한 컴포넌트 메서드의 this또한 컴포넌트가 바인딩되어 있을까요?? input 요소에 텍스트를 입력하여 어떻게 동작하고 있는지 확인해보겠습니다.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ""
};
}
onChange(e) {
const { value } = e.target;
this.setState({ inputValue: value });
}
render() {
const { inputValue } = this.state;
return (
<div className="App">
<input type="text" onChange={this.onChange} value={inputValue} />
</div>
);
}
}
export default App;
결과는? 이벤트 핸들러의 콜백 함수로 전달한 메서드는 에러가 발생합니다.
메서드가 실행될 때 바인딩된 this가 setState를 참조할 수 없는 것인데요 위에서 분명 컴포넌트 메서드는 this가 컴포넌트를 가리키고 있었기 때문에 setState를 참조할 수 있어야하는데 왜 에러가 발생했을까요? 바로 이벤트 발생 시 this가 전역 객체인 window에 바인딩 되어있기 때문에 this.state 참조가 불가능해 집니다. 그렇다면 this에 컴포넌트가 바인딩되도록 하는 방법은 무엇이 있을까요?
📌 해결방법
1. bind() 메소드 사용
2. 화살표 함수 사용
Function 객체에서 제공하는 this 값을 명시적으로 지정 가능한 bind 메서드를 사용해 컴포넌트가 this에 바인딩된 한 함수를 생성합니다.
constructor(props) {
super(props);
this.state = {
inputValue: ""
};
this.onChange = this.onChage.bind(this);
}
onChange(e) {
const { value } = e.target;
this.setState({ inputValue: value });
}
render() {
const { inputValue } = this.state;
return (
<div className="App">
<input type="text" onChange={this.onChange} value={inputValue} />
</div>
);
}
'Programming > React' 카테고리의 다른 글
배열 key props (0) | 2023.04.28 |
---|---|
useState의 렌더링, 함수형 업데이트 (0) | 2023.04.28 |
React PureComponent를 알아보자! (0) | 2021.09.19 |
React portal에 대해 알아보자! (0) | 2021.09.17 |
React 컴포넌트 라이프사이클 (0) | 2021.09.11 |