addEventlistener를 사용하여 DOM으로 event handler를 추가했듯이, React에서는 React element에 이벤트를 추가해서 event handler 함수를 넘겨준다.
class Button extends React.Component {
constructor() {
super();
this.state = {
clicked: false
}
}
render() {
return (
<div
className={`btn ${this.props.type === 'like' ? 'like-btn' : ''}`}
onClick={()=>{this.setState({ clicked: !this.state.clicked })}}
>
{this.state.clicked ? '좋아요' : '싫어요'}
</div>
);
}
}
ReactDOM.render(
<Button type="like" />,
document.getElementById('root')
);
Button 컴포넌트의 <div>
태그안에 onClick
이벤트에 ()=>{this.setState({ clicked: !this.state.Clicked })}
라고 event handler를 넘겨주었다. 해당 요소를 click 할 때마다 event handler 함수가 실행된다.
그런데 render 메서드 내부의 React 요소에 함수가 포함되어있어서 코드가 깔끔하지 않다. event handler 부분을 분리해서 함수를 밖으로 빼도록 하자.
class Button extends React.Component {
constructor() {
super();
this.state = {
clicked: false
}
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
clicked: !this.state.clicked
});
}
render() {
return (
<div
className={`btn ${this.props.type === 'like' ? 'like-btn' : ''}`}
onClick={this.handleClick}
>
{this.state.clicked ? '좋아요' : '싫어요'}
</div>
);
}
}
ReactDOM.render(
<Button type="like" />,
document.getElementById('root')
);
Button 컴포넌트에 handleClick 메서드를 추가했고, onClick
이벤트에 this.handleClick event handler
함수를 넘겨주었다.
this.handleClick = this.handleClick.bind(this);
this.handleClick
가 this.handleClick.bind(this)
라는 뜻이다. 원래 아래의 코드처럼 써야하는데 길어지니까 constructor에서 this.handleClick에 이미 this를 bind 시킨 handleClick 메서드를 대입해주었다.
render() {
return (
<div
className={`btn ${this.props.type === 'like' ? 'like-btn' : ''}`}
onClick={this.handleClick.bind(this)}
>
{this.state.clicked ? '좋아요' : '싫어요'}
</div>
);
}
handleClick 메서드 내에서 this 키워드를 사용하고 있는데, 이 this는 Button 컴포넌트의 context여야 한다. handleClick.bind(this)라고 작성해준 위치에서 그 this를 handleClick에 넘겨서 handleClick 메서드 내에서도 같은 this를 쓰겠다는 이야기이다.
그래야만 Button 컴포넌트의 this.state에 접근하고, setState 함수도 쓸 수 있기 때문이다. 이벤트에 event handler 함수를 넘길때 bind를 해주지 않으면 event handler 함수 내에서 this의 context를 잃어버려서 this가 undefined
가 된다.
React 요소에 이벤트를 추가할 경우 bind(this)를 해줘야 한다는 것만 기억하자.