[React] 이벤트처리(1) - (this바인딩, 클래스필드-class field, 화살표함수)

권준혁·2020년 11월 1일
0

React

목록 보기
13/20
post-thumbnail
post-custom-banner

안녕하세요!
이번 포스팅은 리액트에서 이벤트핸들링하는 방법들을 알아보겠습니다.
이벤트핸들링하는 방법들의 중심에는 함수바인딩과 성능문제 이슈가 있었습니다.

이벤트처리 메서드 this바인딩

이벤트 처리 메서드가 컴포넌트 인스턴스에 접근할 필요가 없다면 클래스 바깥에서 정의할 수 있습니다. 반대로, "this" 를 이용할 때처럼 컴포넌트 인스턴스에 접근하는 경우에는 클래스 내부에 작성해야 합니다.
클래스 바깥에서 구현하면 테스트코드를 작성하기 쉽다는 장점이 있습니다.
"this"에 접근해야 한다면 함수 바인딩을 사용해야 하는데,

컴포넌트 인스턴스에 접근하기 위해 바인딩하는 두 가지방법

  • render함수에서 바인딩
  • 생성자에서 바인딩

이 두가지 방법을 먼저 살펴보겠습니다.

이렇게 세 종류의 버튼이 있고 상탯값 count를 증가시키거나 감소시키는 기능을 하는 이벤트를 만들어보겠습니다.

import React from 'react'

export default class MyComponent extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            count : 0
        }
        this.onClickInc = this.onClickInc.bind(this)
    }
    onClickInc() {
        const {count} = this.state;
        this.setState({count : count +1 })
    }
    onClickDec() {
        const {count} = this.state;
        this.setState({count : count -1 })
    }
    onClickHello(e) {
        e.preventDefault();
        alert('hello')
    }
    componentDidUpdate() {
        console.log(this.state.count)
    }
    render () {
        return (
            <div>
                <button onClick={this.onClickDec.bind(this)}>Decrease</button>
                <button onClick={this.onClickInc}>Increase</button>
                <button onClick={this.onClickHello}>Alert</button>
            </div>
        )
    }
}

렌더링 하는 부분을 보면 세 개의 button이 있고 각각 다른 onClick 이벤트 메서드를 갖고 있습니다.
this객체와 무관한 onClickHello 메서드는 함수 바인딩이 필요없습니다.
나머지 두 개의 함수
onClickDec는 render 메서드 내부에서 바인딩하고있고,
onClickInc는 constructor에서 바인딩을 하고 있습니다.
둘 중 더 나은 방법은 constructor에서 바인딩하는 것 입니다.
render메서드 내에서 바인딩을 하게되면 렌더링할 때마다 바인딩하므로 새로운 함수가 생성됩니다.
constructor에서 첫 렌더링시에만 바인딩을 생성하는 방법이 더 낫습니다.

클래스필드 (class field)

클래스필드는 거~의 정식문법으로 확정된 문법입니다. 바벨을 이용하면 정식문법이 아니지만 사용할 수 있습니다. 지금까지 본 모든 책이나 문서에서 안심하고 사용하라고 합니다.
이 클래스필드는 함수에 바인딩을 적용하면서 렌더링성능과 가독성까지 높힐 수 있습니다.
방금 살펴봤던 constructor내 에서 바인딩하는 방법이나 render함수 내에서 바인딩 하는 것 보다 낫습니다.
render함수에서 바인딩할 때의 성능상의 문제도 없고, constructor에서 바인딩할 때의 번거로움도 없습니다.

코드를 수정해보겠습니다.

import React from 'react'

export default class MyComponent extends React.Component {
    state = {
        count : 0
    }
    onClickInc = () => {
        const {count} = this.state;
        this.setState({count : count +1 })
    }
    onClickDec = () => {
        const {count} = this.state;
        this.setState({count : count -1 })
    }
    onClickHello = (e) => {
        e.preventDefault();
        alert('hello')
    }
    componentDidUpdate() {
        console.log(this.state.count)
    }
    render () {
        return (
            <div>
                <button onClick={this.onClickDec}>Decrease</button>
                <button onClick={this.onClickInc}>Increase</button>
                <button onClick={this.onClickHello}>Alert</button>
            </div>
        )
    }
}

constructor가 없어지고, 클래스 내의 함수들은 화살표 함수로 생성합니다. 화살표함수가 자동으로 바인딩을 해줍니다.

클래스형으로 컴포넌트를 작성한다면, 간편하고 성능상으로도 이점이 있는 클래스필드가 좋은 선택지가 될 것 같습니다.

읽어주셔서 감사합니다!

profile
웹 프론트엔드, RN앱 개발자입니다.
post-custom-banner

0개의 댓글