본문 바로가기

React

React 시작하기 - 06 - 이벤트 핸들링하기, this 바인딩 해주기, e 합성 이벤트

리액트에서 엘리먼트를 만들 때 event 처리를 해줄 수 있다.

이는 DOM에서 onclick, onchange 등과 비슷하게 사용할 수 있다.

그러나 다른 점도 몇 가지 있다.

일단 리액트에서 사용하는 e는 합성 이벤트다.

DOM의 이벤트 객체와 비슷하지만 조금 다른 부분도 있다.

또한 함수를 부르는 위치에 따라 this 가 위치에 따라 바뀌기 때문에 

bind를 따로 해주어야 한다.

<body>
    
    <div id="root1">

    </div>
    <div id="border1"></div>


    <!-- react cdn -->
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <!-- react dom cdn -->
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <!-- babel cdn -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <!-- define type as a babel  -->
    <script type="text/babel">
        class MakeBorder extends React.Component {
            render() {
                return <p>--------------------------------root{this.props.num}----------------------------</p>
            }
        }
        // --------------------------root1---------------------------------
        // 이벤트 핸들링
        // React 엘리먼트에서 이벤트를 처리하는 방식은 DOM 엘리먼트에서 이벤트를 처리하는 방식과 매우 비슷하다.
        // 다만 몇 가지 문법 차이가 있다.
        // 1. HTML DOM 이벤트는 속성명을 소문자로 쓰지만 React 이벤트는 캐멀 케이스(camelCase)를 사용한다.
        // 2. JSX를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달한다.
        // 다음 예시를 보자.
        // <button onclick="activateLasers()"> Run Test </button>
        // HTML DOM 이벤트는 위처럼 쓰지만 React 이벤트는 아래와 같다.
        // <button onClick={activateLasers}> Run Test </button>
        
        // 기본 동작 방지하기
        // 또 다른 차이점으로, React에서는 false를 반환해도 기본 동작을 방지할 수 없다.
        // 반드시 preventDefault를 명시적으로 호출해야 한다.
        // 예를 들어 다음 HTML 코드를 보자.
        // <form onsubmit="console.log('You clicked submit.'); return false">
        //     <button type="submit">Submit</button>
        // </form>
        // HTML 코드는 위와 같이 쓰고  React는 아래와 같이 쓴다.
        // function Form() {
        //     function handleSubmit(e) {
        //         e.preventDefault();
        //         console.log('You clicked submit.');
        //     }

        //     return (
        //         <form onSubmit={handleSubmit}>
        //            <button type="submit">Submit</button>
        //         </form>
        //     );
        // }
        // 덧붙여서, 위에 있는 예시에서 handleSubmit 함수가 전달 받는 'e'는 합성 이벤트다.
        // React는 W3C 명세에 따라 합성 이벤트를 정의하기 때문에 브라우저 호환성에 대해 걱정할 필요는 없다.
        // 그렇지만 React 이벤트는 브라우저 고유 이벤트와 정확하게 똑같이 작동하지는 않는다.
        // 합성 이벤트에 대해 더 자세히 알고 싶다면 아래 페이지를 참고하자.
        // https://ko.reactjs.org/docs/events.html


        // 클래스 메소드에서 this 사용
        // JavaScript에서 클래스 메소드는 기본적으로 바인딩되어 있지가 않다. 
        // this.handleClick을 바인딩하지 않고 onClick에 전달하였다면, 함수가 실제 호출될 때 this는 undefined가 된다.
        // 이는 React만의 특수한 동작이 아니며, JavaScript에서 함수가 작동하는 방식 자체이 그렇다.
        // onClick={this.handleClick}과 같이 뒤에 ()를 사용하지 않고 메소드를 참조할 경우, 해당 메소드를 바인딩 해야 한다.
        class Toggle extends React.Component {
            constructor(props) {
                super(props);
                this.state = {isToggleOn: true};

                // 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 한다.
                // 바인딩하지 않으면 밑에 handleClick() 함수에서 this를 undefined로 인식하게 된다.
                this.handleClick = this.handleClick.bind(this);
            }

            handleClick() {
                this.setState(prevState => ({
                    isToggleOn: !prevState.isToggleOn
                }));
            }

            render() {
                return (
                    <button onClick={this.handleClick}>
                        {this.state.isToggleOn ? 'ON' : 'OFF'}
                    </button>
                );
            }
        }

        ReactDOM.render(
        <Toggle />,
        document.getElementById('root1')
        );
        ReactDOM.render(<MakeBorder num="1"/>, document.getElementById('border1'));

    </script>
</body>

- 220527

 

참고자료 -

https://ko.reactjs.org/docs/handling-events.html

반응형