[React] Event의 정의 및 처리

    Handling Events

    1. Event

    • 특정 사건을 의미 → 예) 사용자가 버튼을 클릭하는 사건  ✅ 버튼 클릭 이벤트
    • Event를 처리하다. = Event를 Handling 한다.

    DOM의 Event

    <button onclick="activate()">
    	Activate
    </button>

     

    리액트의 Event

    <button onClick={activate}>
    	Activate
    </button>
    • Event 이름이 CamelCase(카멜 표기법)로 표기된다.
    • Event를 처리할 함수를 문자열로 전달(DOM)하지 않고, 함수 그대로 전달한다.

     

    2. Event Handler

    • 어떤 이벤트가 발생했을 때, 해당 이벤트를 처리하는 함수
    • Event Listener라고 부르기도 한다.
    class Toggle extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = { isToggleOn: true}
    
        // callback에서 'this'를 사용하기 위해서는 바인딩을 필수적으로 해줘야 한다.
        this.handleClick = this.handleClick.bind(this)
      }
    
      handleClick() {
        this.setState(prevState => ({
          isToggleOn: !prevState.isToggleOn
        }));
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            { this.state.isToggleOn ? '켜짐' : '꺼짐' }
          </button>
        )
      }
    }

    자바스크립트에서는 기본적으로 클래스 함수들이 바운드되지 않는다.

    그래서 bind()를 쓰지 않으면, this.handleClick은 global scope에서 호출된다.  ( ✅ undefined )

    그러므로, 함수의 이름 뒤에 괄호 없이 사용하려면 bind() 해줘야 한다.

     

    bind()

    2개의 매개변수를 받는다.

    • 첫 번째, 함수 내부적으로 this를 무엇으로 쓸 것인가.
    • 두 번째, 함수가 호출될 때마다 사용될 인자를 지정할 수 있다.

    참고 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

     

     

    bind를 사용하기 번거롭다면, Class fields syntax를 사용한다.

    • Class fields syntax : 클래스 블록 안에서 할당 연산자(=)를 이용해 인스턴스 속성을 지정할 수 있는 문법
    class MyButton extends React.Component {
      handleClick = () => { // Class fields syntax
        console.log('this is:', this)
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            클릭
          </button>
        )
      }
    }

     

    또는, Event handler를 넣는 곳에 Arrow function 사용한다.

    • MyButton 컴포넌트가 렌더링 될 때마다 다른 콜백함수가 생성되는 문제가 있다.
    • 이 콜백함수가 다른 하위 컴포넌트의 prop으로 넘겨지게 되면 하위 컴포넌트에서
      추가적인 렌더링 발생하므로, 성능 문제를 위해선 피하는 게 좋다.
    class MyButton extends React.Component {
      handleClick() {
        console.log('this is:', this)
      }
    
      render() {
        return (
          <button onClick={()=> this.handleClick()}>
          <!-- Arrow function 사용 -->
            클릭
          </button>
        )
      }
    }

    3. 함수 컴포넌트에서 이벤트 처리

    이벤트를 넣어줄 때 this를 사용하지 않고, 곧바로 정의한 Event handler를 넣어준다. ( onClick )

     

    function Toggle(props){
      const [isToggleOn, setIsToggleOn] = useState(true);
      
      // 방법1. 함수 안에 함수로 정의
      function handleClick() {
        setIsToggleOn((isToggleOn) => !isToggleOn)
      }
    	
      // 방법2. arrow function을 사용하여 정의
      const handleClick = () => {
        setIsToggleOn((isToggleOn) => !isToggleOn);
      }
    
      return (
        <button onClick={handleClick}>
          {isToggleOn ? "켜짐" : "꺼짐"}
        </button>
      )
    }

    4.  Arguments

     

    함수(Event Handler)에 전달할 데이터를 의미한다.

    Parameter, 매개변수라고도 한다.

     

    📌 클래스 컴포넌트에서 매개변수 전달하기

    <button onClick={(event) => this.deleteItem(id, event)}>삭제하기</button>
    <!-- event를 명시적으로 두 번째 매개변수로 넣어줌 -->
    
    <button onClick={this.deleteItem.bind(this, id)}>삭제하기</button>
    <!-- event가 자동으로 id이후에 두 번째 매개변수로 전달된다. -->

    📌 함수 컴포넌트에서 매개변수 전달하기

    function MyButton(props) {
      const handleDelete = (id, event) => {
        console.log(id, event.target);
      }
    
      return (
        <button onClick={(event) => {handleDelete(1, event)}}>
          삭제하기
        </button>
      )
    }


    🚀 참고

     

    더 공부할 것

    댓글