티스토리 뷰

React.JS

[React.JS] Handling Events

버미노트 2017. 4. 7. 21:17


React.JS



Handling Events



HTML 이벤트 핸들러 VS React 이벤트 핸들러

React.JS에서 이벤트 핸들링은 DOM에서의 이벤트 핸들링과 비슷하지만, 몇가지 차이가 있습니다.


이벤트 핸들러 등록

HTML에서 이벤트 핸들러 등록 방법은 아래와 같습니다. (이벤트 핸들링 방법이 여러가지 있겠지만...)

<button onclick="htmlEventHandler()">
  BUTTON
</button>

React에서 이벤트 핸들러 등록 방법은 아래와 같습니다.

<button onClick={reactEventHandler}>
  BUTTON
</button>


이벤트의 기본 동작 막기

HTML에서 이벤트의 기본 동작을 막기 위해서는 return false를 이용해야 했습니다.
<a href="http://beomy.tistory.com" onclick="console.log("This was click"); return false;" target="_blank" >
  LINK
</a>

하지만 React에서 return false로는 이벤트의 기본 동작을 막지 못합니다. preventDefault를 사용해야 이벤트의 기본 동작을 막을 수 있습니다.

function EventHandlerTest() {
  function handlerClick(e) {
    e.preventDefault();
    console.log("This was click");
  }
  
  return (
    <a href="http://beomy.tistory.com" onClick={handlerClick} target="_blank">LINK</a>
  )
}

ReactDOM.render(
  <EventHandlerTest />,
  document.getElementById('root')
);

CodePen으로 예제 확인하기


위의 예제는 e.preventDefault()로 a 태그의 href으로 연결되는 동작이 안하는 것을 확인 할 수 있습니다. 하지만 e.preventDefault()가 아닌 return false로 변경할 경우 a 태그의 href로 링크가 연결됩니다.



이벤트 핸들러 정의

DOM element가 생성 된 후, addEventListener를 호출하는 방식이 아닌, element가 처음 랜더링 할 때, 이벤트 핸들러를 제공해야 합니다.

일반적으로 React의 이벤트 핸들러를 정의 할 때 ES6에서 추가된 Class를 사용합니다. 이벤트 핸들러는 Class의 메소드로 정의합니다.

class EventHandlerTest extends React.Component {
  constructor(props) {
    super(props);
    this.state = {counter: 0};
    
    this.handlerCounter = this.handlerCounter.bind(this);
  }
  
  handlerCounter() {
    this.setState(prevState => ({
      counter: prevState.counter + 1
    }));
  }
  
  render() {
    return (
      <div>
        <h1>Click Count : {this.state.counter}</h1>
        <button onClick={this.handlerCounter}>click</button>
      </div>
    );
  }
}
  
ReactDOM.render(
  <EventHandlerTest />,
  document.getElementById('root')
);

CodePen으로 예제 확인하기


  • 6번 줄 handlerCounter는 클릭시 호출되는 콜백함수이기 때문에, this를 바인딩해야 합니다. this를 바인딩하지 않으면 콜백으로 실행되는 handlerCounter의 this는 window객체가 되기 때문에 this.setState를 사용할 수 없게 됩니다.
  • 9~13번 줄 클릭시 호출 될 이벤트 핸들러의 구현 부분입니다.
  • 19번 줄 onClick으로 클릭시 실행되는 핸들러 등록 부분입니다.


6번째 줄에서 사용한 bind 없이 이벤트 핸들러를 등록할 수 있습니다.

handlerCounter = () => {
  counter: prevState.counter + 1
};

화살표 함수를 사용하면 생성자에서 this를 바인딩하지 않아도 됩니다. 그 이유는 화살표 함수는 this를 바인딩하지 않아, 콜백으로 handlerCounter() 함수가 실행 될 때, this는 window객체가 아닌 EventHandlerTest객체가 됩니다. ([자바스크립트] ES6(ECMA Script 6) - 화살표 함수(Arrow function) 참고)

또 다른 방법으로 이벤트 핸들러를 등록할 때 화살표 함수를 이용하는 방법이 있습니다.

handlerCounter() {
  this.setState(prevState => ({
    counter: prevState.counter + 1
  }));
}
  
render() {
  return (
    <div>
      <h1>Click Count : {this.state.counter}</h1>
      <button onClick={(e) => this.handlerCounter(e)}>click</button>
    </div>
  );
}

위와 같은 방법은 매번 랜더링 될 때마다 서로 다른 콜백이 생성되게 됩니다. 콜백이 하위 컴포넌츠에 절달되게 되면 하위 컴포넌츠가 다시 랜더링 될 수 있기 때문에, 성능을 위해서라도 생성자에서 this를 바인딩하는 방법이나, 이벤트 핸들러를 화살표 함수로 구현하는 것이 좋습니다.





참고 - https://facebook.github.io/react/docs/handling-events.html

'React.JS' 카테고리의 다른 글

[React.JS] Forms  (0) 2017.04.22
[React.JS] List와 Key  (0) 2017.04.18
[React.JS] State와 Lifecycle  (0) 2017.04.06
[React.JS] Componenst와 Props  (0) 2017.04.02
[React.JS] JSX  (0) 2017.04.02
댓글
공지사항
최근에 올라온 글