event

class component에서의 Event 처리 방법에 대해서 살펴본다.

Event 처리

이벤트를 처리하기 위해서는 함수가 필요하며, 클래스 컴포넌트에 함수를 배치하는 방법은 여러 가지가 존재한다.

  • 화살표 함수(Arrow function)

  • 클래스 메소드 지정

  • Function.prototype.call() / .apply()

  • Function.prototype.bind()

  • Babel transform-class-properties 문법

Arrow function

화살표 함수로 이벤트를 처리할 경우 다음과 같이 작성한다. 다음 JSX 코드는 버튼을 클릭할 경우 알림창이 출력되는 코드이다.

<button onClick={()=>{window.alert('click event')}}>click</button>

추가 메소드를 구현하지 않아도 되므로 인라인으로 간편하게 처리할 수 있으나, 코드가 길어지면 가독성이 떨어지므로 간단한 코드 작성 시 유리하다. Arrow function 내에서 this라는 키워드를 사용할 경우 해당 컴포넌트 객체에 접근할 수 있다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React CDN Example</title>
    
</head>
<body>

    <div id="app"></div>
    
    <!-- 개발용 CDN -->
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

    <!-- 배포용 CDN -->
    <!-- <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> -->
    <!-- <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> -->

    <!-- 바벨 CDN(using JSX) -->
    <script src=" https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script type="text/babel">
        class MainComponent extends React.Component {
            render(){
                return (
                    <>
                        <button onClick={()=>{ alert('click event') }}>click</button>
                    </>
                );
            }
        }

        const app = ReactDOM.createRoot(document.querySelector("#app"));
        app.render(
            <MainComponent/>
        );
    </script>
</body>
</html>

클래스 메소드 지정

React Component Class 내부에 메소드를 만들고 이를 지정하여 호출할 수 있다.

class MainComponent extends React.Component {

    clickEventProcessor(){
        window.alert('click event');
    }

    render(){
        return (
            <>
                <button onClick={this.clickEventProcessor}>click</button>
            </>
        );
    }
}

클래스 메소드로 이벤트를 처리할 경우 문제점

위와 같이 클래스에 생성한 메소드로 이벤트를 처리할 경우 react component에 접근할 수 없다. thisundefined로 출력되며, state, props 등 컴포넌트의 다른 구성요소에 접근할 수 없어 컴포넌트와 상관 없는 작업만 처리할 수 있다.

class MainComponent extends React.Component {
    clickEventProcessor(){
        console.log(this);
    }
    render(){
        return (
            <>
                <button onClick={this.clickEventProcessor}>click</button>
            </>
        );
    }
}

Function.prototype.call() / .apply()

Function에서 제공하는 call 함수와 apply 함수를 이용하면 this를 설정하며 함수 호출이 가능하다. 이를 이용하여 다음과 같이 이벤트를 설정할 수 있다.

class MainComponent extends React.Component {
    
    clickEventProcessor(){
        console.log(this);
        window.alert('click event');
    }
    
    render(){
        return (
            <>
                <button onClick={()=>this.clickEventProcessor.call(this)}>click</button>
                <button onClick={()=>this.clickEventProcessor.apply(this)}>click</button>
            </>
        );
    }
}

Function.prototype.call()Function.prototype.apply()는 동일한 기능을 수행하지만 다음 차이가 있다.

  • Function.prorotype.apply()는 인수를 배열로 전달한다.

  • Function.prototype.call()은 인수를 그대로 전달한다.

Function.prototype.bind()

Function.prototype.bind()를 사용하여 이벤트 처리 함수를 재할당 하여 사용하는 방법이 있다.

class MainComponent extends React.Component {

    constructor(){
        super();

        this.clickEventProcessor = this.clickEventProcessor.bind(this);
    }

    clickEventProcessor(){
        console.log(this);
        window.alert('click event');
    }

    render(){
        return (
            <>
                <button onClick={this.clickEventProcessor}>click</button>
            </>
        );
    }
}

핵심 코드는 생성자(constructor)에 있는 bind 코드이다.

this.clickEventProcessor = this.clickEventProcessor.bind(this);

clickEventProcessor에 this를 설정하여 재할당 한 뒤 사용하면 정상적으로 이벤트 함수에서 this가 MainComponent로 출력된다.

Babel class-transform-properties

Babel에서 제공하는 변환 코드를 사용하여 Function.prototype.bind() 대신 사용할 수 있다. 다음과 같은 형태로 이벤트 처리 메소드를 작성한다.

class MainComponent extends React.Component {

    constructor(){
        super();
    }

    clickEventProcessor = ()=>{
        console.log(this);
        window.alert('click event');
    }

    render(){
        return (
            <>
                <button onClick={this.clickEventProcessor}>click</button>
            </>
        );
    }
}

주의사항은 처리 함수는 반드시 화살표 함수로 작성해야 하며, 다음과 같이 작성하면 안된다는 것이다.

clickEventProcessor = function(){
    console.log(this);
    window.alert('click event');
}

실행하면 정상적으로 출력되는 것을 확인할 수 있다.

결론

이벤트 처리는 다음과 같은 방법으로 한다.

지원하는 이벤트의 종류는 다음과 같다.

  • Clipboard

  • Composition

  • Keyword

  • Focus

  • Form

  • Generic

  • Mouse

  • Pointer

  • Selection

  • Touch

  • UI

  • Wheel

  • Media

  • Image

  • Animation

  • Transition

  • ETC

Last updated