React elements에 대한 event handling은 DOM element에 대한 event handling과 매우 유사하다.
하지만 몇 가지 차이점이 있다.
React element 이벤트 핸들링 기본
- React 에서 events 이름은 반드시 camelCase(카멜케이스, 낙타표기)를 사용해야 한다.
- React 에서 event handler(이벤트 핸들러)는 JSX 형태로 함수를 표기한다.
// 기존 DOM element 에서 사용하는 방법
<button onclick="activateLasers()">
Activate Lasers
</button>
// React에서 사용하는 방법
<button onClick={activateLasers}>
Activate Lasers
</button>
위 예제를 살펴보면, onClick과 같이 camelCase로 이벤트 이름을 설정하고, event handler의 연결은 JSX 표기인 { } 를 사용하고 있다.
※ React element 이벤트 핸들러 연결 시 this 객체 사용 주의 ※
다음 코드를 살펴보자
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
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>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
위 코드의 로직은, button에 onClick이 발생하면, Toggle 컴포넌트에 있는 handleClick 함수를 호출하도록 연결하고 있다.
여기에서 constructor에 binding 부분을 주목해보자.
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
살펴 보면, this.handleClick 함수에 this를 bind 하고 있다.
여기서 this는 Toggle 컴포넌트를 뜻한다. 왜 this를 bind 해야 할까?
사실 내용은 간단하다. JSX를 사용해서, this.handleClick을 연결했을 때, JSX는 this를 bind 하지 않는다.
따라서, 핸들러 함수 내부에서 this 객체(컴포넌트 자기자신)를 사용하려면, 그 전에 미리 this를 bind 해줘야 한다.
handleClick() {
// 여기서 this(Toggle)을 사용하려면, 반드시 this가 bind 되어 있어야 한다.!
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
※ this를 bind하는 기본적인 방법 ※
// 1. constructor에서 method에 this을 bind 하기
constructor(props) {
super(props);
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
또는 아래와 같이 this를 bind할 수도 있다.
// 2. event hanler함수를 연결할때 bind를 하기
render() {
return (
<button onClick={this.handleClick.bind(this)}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
위 2가지 방법이 가장 일반적으로 event handler 함수에 this를 bind 하는 방법이다.
react document에서는 추가적으로 2가지 방법을 더 소개하고 있다.
※ this를 bind하는 추가적인 방법 ※
- event handler 를 정의하는 시점에 es6 문법의 array function style로 정의
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
이 방법은 babel 컴파일 중 에러가 발생하는 경우도 존재한다.이 방법이 되는 이유는 es6의 () => 문법이 this를 bind 해주는 형태이기 때문이다.
- JSX로 event handler를 연결할 때 anonymouse 형태의 arrow function을 사용하기
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// This syntax ensures `this` is bound within handleClick
return (
<button onClick={(e) => this.handleClick(e)}>
Click me
</button>
);
}
}
// 이 방식은 사실 아래 코드처럼 되는 것과 같다.
let self = this;
onClick = function (e) {
self.handleClick(e); // caller인 self (LogginButton) 컴포넌트가 this로 bind
}
이 방법은 babel 컴파일 중 에러가 발생하지 않는다. 이 방법이 되는 이유는 anonymouse로 생성된 function에서 명시적으로 this.handleClick(e)을 호출하기 때문에 this가 handler에 bind 된다.
이 방법의 단점은 component(LogginButton)이 render 될 때마다 그때마다 anonymouse 함수가 생성되는데 있다. 일반적으로 대부분의 경우에는 큰 문제 없지만, event handler가 대용량의 re-rendering이 필요한 경우에는 성능상의 문제가 발생할 수 있다.
정리
- React 에서 event handler함수는 camelCase(낙타표기)를 사용해야 한다.
- React 에서 event handler(이벤트 핸들러)는 JSX 형태로 함수를 표기한다.
- React 에서 event handler 표기시 this객체 bind에 주의하여야 한다.
- React 에서 event handler에 this객체 bind는 일반적으로 생성자(constructor)에서 하는 것을 권장한다.
'Framework | Library > React.js' 카테고리의 다른 글
[React] 이벤트 핸들러에 인자 전달하기 (0) | 2022.07.12 |
---|---|
[React] Virtual DOM(VDOM)과 Diffing 알고리즘 (0) | 2022.07.12 |
[React] React hooks - useReducer (0) | 2022.07.12 |
[React] props (0) | 2022.07.11 |