리액트 이벤트 핸들링 - liaegteu ibenteu haendeulling

study

Follow

Oct 4, 2018

·

7 min read

[리액트 교과서] 6장 React 에서 이벤트 다루기

6장 React 에서 이벤트 다루기

React는 특정 이벤트만을 지원하므로 React가 지원하지 않는 이벤트를 다루는 방법도 살펴보자.

React에서 DOM 이벤트 다루기

React 엘리먼트를 만드는 방법

  • JSX로 작성한 엘리먼트에 속성 값으로 이벤트 핸들러를 정의한다.
  • 속성으로 사용하는 이벤트 이름은 표준 W3C DOM 이벤트를 onClick, onMouserOver처럼 카멜 표기법으로 작성한다.
<button onClick={(function(event){
console.log(this,event)
}).bind(this)}>
save
</button>

bind(this)로 하지 않아도 되는 경우

  • this를 이용해서해당 클래스를 참조할 필요가 없을 때
  • ES6+ 클래스 대신 예전 방식인 React.createClass()를 사용할 때, 이때는 createClass()가 자동으로 바인딩한다.
  • 화살표 함수(()=>{})를 사용할 때
  • render()에서 같은 메서드를 한 번 이상 사용한다면 새성자에서 바인딩하여 중복을 줄 일 수 있다.
class SaveButton extends React.Component{
constructor(props){
super(props);
this.handleSave=this.handleSave.bind(this);
}
handleSave(event){
console.log(this,event)
}
render(){
return <button onClick={this.handleSave}>
Save
</button>
}
}
  • 이벤트 핸들러를 생성자에서 바인딩하면 중복을 제거할 수 있고, 모든 바인딩을 한곳에서 작성할 수 있으므로 위의 방법을 추천한다.

React버전 15에서 지원하는 DOM이벤트

캡처 및 버블링 단계

  • React는 명령형이 아니라 선언형 스타일이므로, 객체를 조작할 필요가 없고 jQuery 처럼 이벤트를 등록하지 않는다. 대신, onClick={handleSave} 처럼 JSX 에 속성으로 이벤트를 선언한다.
  • onMouseOver 같은 이베즈는 버블링 단계의 이벤트에서 실행된다.
  • 캡쳐 단계 → 대상 단계 → 버블링단계
  • 대상요소와 그상위 요소에 같은 이벤트가 있을 때 단계 간의 구분이 중요해진다. 버블링 모드에서는 이벤트가 가장 내부에 있는 대상 요소에서 이벤트를 캡처한후, 대상 요소의 부모 요소를 시작으로 외부의 상위 요소로 이벤트가 전파된다. 캡처 모드에서는 이벤트가 가장 바깥 쪽의 요소에 의해 캡처된 후 내부 요소로 전파된다.

캡처 이벤트에 이어지는 버블링 이벤트

class Mouse extends React.Component {
render() {
return <div>
<div
style={{border: '1px solid red'}}
onMouseOverCapture={((event)=>{
console.log('mouse over on capture event')
console.dir(event, this)}).bind(this)}
onMouseOver={((event)=>{
console.log('mouse over on bubbling event')
console.dir(event, this)}).bind(this)} >
Open DevTools and move your mouse cursor over here
</div>
</div>
}
}
  • 캡쳐 이벤트가 먼저 출력되고, 이러한 동작 원리를 응용해서 이벤트 전파를 중지시키거나 이벤트 간의 우선순위를 정할 수 있다.

React 이벤트 살펴보기

  • jQuery나 일반적인 자바스크립트에서는 DOM노드에 직접 이벤트 리스너를 연결하지만, React에서는 다른 방법으로 이벤트를 처리한다.
  • 더 나은 방법은 부모요소에 하나의 이벤트 리스너를 두고, 버블링되는 이벤트를 처리하는 것이다 (이벤트를 하위요소에서 처리하지 않으면 DOM트리를 따라 위로 버블링 된다.) React는 내부적으로 상위 요소 및 대상 요소에 연결된 이벤트를 매핑에서 추적한다.
  • 리액트는 이벤트 리스너를 최상위 부모인 document 요소에 연결했다.

React 합성 이벤트 객체 다루기

  • 브라우저에 따라 W3C 명세를 다르게 구현할 수 있다. 브라우저 간의 차이로 인해 이벤트를 처리하는 코드를 작성할 때 크로스 브라우징 문제를 경험할 수 있다. 예를 들어 IE8에서 대상요소를 가져오려면 event.srcElement 에 접근 해야 하지만, Chrome, Safari, Firefox 브라우저 에서는 event.target으로 접근한다.
  • React의 해결책은 브라우저 내장 이벤트를 감싸는 것이다. 웹 페이지를 실행하는 브라우저의 구현에 관계없이, 이벤트가 W3C 명세를 따르도록 만들었다. 내부적으로 React는 합성 이벤트를 위한 특별한 클래스를 사용한다. SyntheticEvent 클래스의 인스턴스를 이벤트 핸들러에 전달 하는 것이다.
class Mouse extends React.Component {
render() {
return <div>
<div
style={{border: '1px solid red'}}
onMouseOver={((event)=>{
console.log('mouse is over with event')
console.dir(event)}).bind(this)} >
Open DevTools and move your mouse cursor over here
</div>
</div>
}
}
React가 지원하지 않는 DOM 이벤트 처리하기
  • 앞에서 리액트가 지원하는 이벤트 목록을 살펴 보았는데, 리액트가 지원하지않는 dom이벤트 들도 있다. 예를 들어, 창 크기가 바뀌는, resize 이벤트에 따라 크기를 크거나 작게 변경하는 ui를 만들어야 할수도 있다. 이 이벤트는 리액트가 지원하지 않는다.
  • 따라서,이러한 미지원이벤트에 연결하려면 리액트 컴포넌트 라이프사이클 이벤트를 사용한다. componentDidMount()에서, window의 resize이벤트리스너를 추가하고, 같은 이벤트리스너를 componentWillUnmount()에서 제거해서 컴포넌트가 dom에서 제거될때 이벤트 리스너도 제거한다.
  • 컴포넌트를 제거한 후에 이벤트 리스너를 방치하는것은 메모리 누수를 일으켜 갑자기 애플리이션이 중단 될 수 있다고 한다.
React를 다른 라이브러리와 통합하기 : jQuery UI 이벤트
  • React에서 제공하지 않는 dom 이벤트를 컴포넌트 라이프사이클 이벤트인 componentDidMount와 componentWillUnmount 에서 등록할 수 있다.
  • jquery이벤트에서 window 로 이벤트를 전달하고, 리액트 컴포넌트 라이프사이클이벤트에서 window에 이벤트 리스너를 연결하는 방식으로 구현할 수 있다.
  • 리액트는 componentDidMount() 라이프사이클 메서드를 통해서 다른 라이브러리의 이벤트를 멋지게 다룰수있다. 리액트는 그다지 자체적인 방식을 강요하지 않으므로, 라이브러리의 이벤트를 멋지게 다룰 수있다. 리액트를 다른 라이브러리와 쉽게 통합할 수 있다는것은 큰 장점이라고 한다. 개발자들은 전체 애플리케이션을 처음부터 다시 작성하지 않고도 서서히 react로 변경하거나, 기존에 사용해온 라이브러리를 리액트와 함께 사용할 수도 있는것이다.

요약

  • onClick은 마우스와 트랙패드의 클릭을 캡처한다.
  • JSX 문법으로 이벤트 리스너를 추가할때는 {a onNAME={this.METHOD}>로 작성한다.
  • constructor() 또는 JSX 를 이용해 bind()로 이벤트 핸들러에 this를 바인딩해서 컴포넌트 클래스의 인스턴스에 접근할 수 있다.
  • componentDidMount()는 브라우저에서만 실행된다. componentWillMount()는 브라우저와 서버측 렌더링에서 모두 실행된다.
  • React는 합성 이벤트 객체를 제공함으로써 거의 대부분의 표준 HTML DOM 이벤트를 지원한다.
  • React를 다른 프레임워크와 통합하거나 React가 지원하지 않는 이벤트를 처리하기 위해 componentDidMount()와 componentWillUnmount()를 사용할 수 있다.

Toplist

최신 우편물

태그