TIL. [React] 이벤트 핸들링 -8/4

예흠·2020년 8월 4일
0

wecode

목록 보기
25/43

* react event handling

회원가입 페이지에서 비밀번호를 제대로 입력했는지 addEventListener 를 사용해서 key 이벤트로 validation check 로직을 구현해봤었습니다.
DOM을 찾아 addEventListener으로 event handler를 추가했었죠.

React에서는 React element에 onClick 이벤트를 추가해서 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')
);

지난 state 포스팅에 있던 코드를 그대로 가져왔습니다.
Button 컴포넌트의 <div> 태그에 onClick이벤트에 ()=>{this.setState({ clicked: !this.state.clicked })} 라고 event handler를 넘겨주었습니다.

해당 요소를 click 할 때마다 event handler 함수가 실행됩니다.
즉, 클릭할 때마다 this.state.clicked 값이 반대의 boolean 값으로 clicked state를 업데이트 합니다

그런데 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 함수를 넘겨주었습니다.

constructor에 추가된 코드를 주목해주세요. (bind는 다른 어떤 것을 call해도 현 this가 call 되도록 한다.)

this.handleClick = this.handleClick.bind(this);

this.handleClick가 this.handleClick.bind(this) 라는 뜻입니다.
원래는 써야하는데 표현이 길어지니까 constructor에서 this.handleClick에 이미 this를 bind시킨 handleClick 메서드를 대입해주었습니다.

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가 됩니다.

profile
노래하는 개발자입니다.

0개의 댓글