01.6 React 이벤트 핸들링

React.js

01.6. 리액트의 이벤트


// 사용방법
/* this.setState({
     수정할 필드 이름 : 값
    ,수정할 또 다른 필드 이름 : 값
}); */
    render() {
        return (
            <div>
                <p>안녕하세요.  이름은 {this.props.name} 입니다.</p>
                <p>숫자 : {this.state.number}</p>
                <button onClick={() => {
                    this.setState({
                        number : this.state.number + 1
                    });
                }}>
                더하기
                </button>
            </div>
        );
    }
01.5.3.4 state 값 업데이트 : setState() 게시글에서 클릭이벤트를 작성해 보았다. 사용법은 일반 HTML에서 이벤트를 작성하는 것과 비슷한데, 주의해야 할 사항이 몇 가지 있다.

01.6.1. 이벤트를 사용할 때 주의사항

01.6.1.1. 이벤트 이름은 camelCase로 작성

HTMLonclick 은 리액트에서 onClick으로 작성해야 하고, onkeyuponKeyUp으로 작성해야한다.

01.6.1.2. 이벤트에 실행한 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달

// HTML 
<button onclick="">
// React
<button onClick={() => { }}>

01.6.1.3. DOM 요소에만 이벤트를 설정

div, button, span 등  DOM 요소에는 이벤트를 설정할 수 있지만, 우리가 직접 만든 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다. 앞서 생성한 NewComponentonClick 이벤트를 설정한다면 onClick 이벤트가 아닌 onClickpropsMyComponent에 전달한다.
<NewComponent onClick={doSomething}/>
컴포넌트에 자체적으로 이벤트를 설정할 수 없다. 하지만 전달받은 props를 컴포넌트 내부의 DOM 이벤트로 설정할 수 있다.

<div onClick={this.props.onClick}>
    { /*  (...) */ }
</div>

01.6.2. 이벤트 종류

  • Clipboard Events
  • Composition Events
  • Keyboard Events
  • Focus Events
  • Form Events
  • Mouse Events
  • Pointer Events
  • Selection Events
  • Touch Events
  • UI Events
  • Wheel Events
  • Media Events
  • Image Events
  • Animation Events
  • Transition Events
  • Other Events
리액트 이벤트 매뉴얼을 참고한다.

01.6.3. 사용예제

01.6.3.1. 기본 사용예제

onClick={(e)=>{console.log(e)}}

01.6.3.2. state 값 변경하기

생성자 메서드(constructor)에서 state 초깃값을 설정하고, 이벤트 핸들링 함수 내부에서 this.setState 메서드를 호출하여 state를 업데이트한다.
// 생성한 NewComponent 를 사용해도 되고, 새로운 Component를 사용해도 된다. 단, state에 message가 있어야한다.
    render() {
        return (
            <div>
                <p>이벤트 연습</p>
                <input
                    type='text'
                    name='message'
                    placeholder='입력하세요'
                    value={this.state.message}
                    onChange={
                        (e) => {
                            this.setState({
                                message: e.target.value
                            });
                        }
                    }
                />
            </div>
        );
    }

01.6.3.3. 임시 메서드 활용하기

성능상으로는 차이가 거의 없지만 가독성을 높이기 위해 컴포넌트 임의 메서드를 생성한다.
constructor 메서드에 updateMsg 메서드를 바인딩한다.
constructor(props) {
    super(props);
    this. updateMsg = this. updateMsg.bind(this);
}
컴포넌트 내부에 코드를 작성한다
    // 임의 메서드 생성
    updateMsg(e) {
        this.setState({
            message: e.target.value
        });
    }

    render() {
        return (
            <div>
                <p>이벤트 연습</p>
                <input
                    type='text'
                    name='message'
                    placeholder='입력하세요'
                    value={this.state.message}
                    onChange={this.updateMsg} // 임의 메서드 활용
                />
            </div>
        );
    }
코드의 가독성이 높아져 개발시 도움이 된다.
    // 임의 메서드를 활용하지 않을 경우
    onChange={
        (e) => {
            this.setState({
                message: e.target.value
            });
        }
    }
    // 임의 메서드를 활용하는 경우
    onChange={this.updateMsg}

Property Initializer Syntex 를 사용한 메서드 작성
메서드 바인딩생성자 메서드에서 하는 것이 정식이지만, 메서드를 새로 만들 때마다 constructor도 수정을 해야하는 불편함 때문에 바벨의 transform-class-properties 문법을 사용하여 화살표 함수 형태로 메서드를 정의한다.

import React , { Component } from 'react';
import PropTypes from 'prop-types';

class NewComponent extends Component {

    state = {
        message: ''
    }
    // constructor를 생성하지 않는다
    // 임의 메서드 생성
    updateMsg = (e) => {
        this.setState({
            message: e.target.value
        });
    }

    render() {
        return (
            <div>
                <p>이벤트 연습</p>
                <input
                    type='text'
                    name='message'
                    placeholder='입력하세요'
                    value={this.state.message}
                    onChange={this.updateMsg} // 임의 메서드 활용
                />
            </div>
        );
    }
}

export default NewComponent;

※ input 여러 개 핸들링하기
input 값을 state에 넣는 방법을 배웠다. input이 여러 개일 경우 메서드를 여러 개를 만들기보다 event 객체를 활용하여 처리한다.

import React , { Component } from 'react';
import PropTypes from 'prop-types';

class NewComponent extends Component {

    state = {
         username: '' // 새롭게 추가된 사용자 이름
        ,message: ''
    }

    // 임의 메서드 생성
    updateState = (e) => {
        this.setState({
            // event 객체에 e.target.name 은 해당 인풋의 name 이다.
            [e.target.name] : e.target.value 
        });
    }

    render() {
        return (
            <div>
                <p>이벤트 연습</p>
                <input
                    type='text'
                    name='username'
                    placeholder='사용자이름'
                    value={this.state.message}
                    onChange={this.updateState} // 임의 메서드 활용
                />
                <input
                    type='text'
                    name='message'
                    placeholder='메세지'
                    value={this.state.message}
                    onChange={this.updateState} // 임의 메서드 활용
                />
            </div>
        );
    }
}

export default NewComponent;

리액트에서 이벤트를 다루는 것은 순수 자바스크립트 또는 jQuery를 사용한 웹 애플리케이션에서 이벤트를 다루는 것과 비슷하다. HTML DOM Event를 알고 있다면 리액트 컴포넌트의 이벤트도 쉽게 다룰 수 있다.

댓글

이 블로그의 인기 게시물

01.11 리액트 컴포넌트 CSS 적용 ( CSS Module, Sass, styled-components )

01.9 React 컴포넌트 라이프사이클

01.7 React ref (DOM에 이름 달기)