[React] 이벤트 핸들링/ 함수를 바인딩(전달)하는 올바른 방법 feat. 이벤트 객체, 함수 커링

2023. 2. 12. 00:00프론트엔드/React.js

반응형

 

 

 

이벤트 핸들링

 

리액트에서 이벤트 핸들링은 React 컴포넌트에서 UI 요소에서 발생하는 이벤트(: 클릭, 마우스 오버, 입력 ) 처리하는 것을 의미한다.

이벤트에 함수를 바인딩한다는 것은 UI 요소에 onEvent 속성으로 함수(이벤트 핸들러)를 전달하는 것을 말한다.

 

 

const a = () => {
  console.log("a 함수가 호출됨");
};

const App = () => {
  return (
    <div>
      <button onClick={a()}>1번</button>
      <button onClick={a}>2번</button>
      <button onClick={() => a()}>3번</button>
    </div>
  );
};

 

각각의 버튼은 어떻게 작동할까?

비슷해보이지만 다른 결과를 가져올 수 있는데 그 차이점을 알아보자.

 

이벤트에 함수 바인딩하기

1. <button onClick={a()}>1번</button>

이 경우 함수의 호출 결과가 적용이 되고 버튼을 클릭할 때가 아닌,

컴포넌트가 렌더링 될 때에 console.log가 실행이 되고

return 값이 없으므로 버튼 클릭 시 아무런 결과도 일어나지 않는다.

 

https://aboveimagine.tistory.com/115

 

2. <button onClick={a}>2번</button>

이 경우 클릭될 때마다 a 함수가 정상적으로 호출된다.

 

3. <button onClick={() => a()}>3번</button>

클릭될 때마다 해당 익명 함수가 호출되고, 그 안에서 a 함수가 호출된다.

2번 버튼과 함수를 호출하는 방식의 차이는 있으나 결과적으로 같은 결과를 보여준다.

단, 함수에 전달할 매개인자가 필요하다면 이 방식을 사용할 것.

 

이벤트 객체

이벤트 객체란, 이벤트를 발생시킨 요소와 발생한 이벤트에 대한 정보를 제공하는 것을 말한다.

예를 들면 사용자가 버튼을 클릭하면, 그 버튼의 textContent(또는 innerHTML)을 이용해 메뉴의 이름을 가져올 수 있다.

이벤트 객체는 사용자 입력(onclick, onkeyup, onscroll 등)을 트리거로 발생한 이벤트 정보를 담은 객체이다.

 

이벤트가 발생하면, 이벤트 객체는 동적으로 생성되어, 이벤트 핸들러에 인자로 암묵적으로 전달된다.

 

const handleOnClick = (e) => console.log(e);

<button onClick={handleOnClick}>button</button>

이렇게 함수 호출 시 인자를 따로 넘겨 주지 않아도 e, event 등으로 바로 불러올 수 있다.

 

하지만 이벤트 객체 말고 다른 인자를 받고 싶다면, 그냥 함수 호출이 아닌 익명함수 내부에서 부를 수 있다.

const handleOnClick = (name, e) => {
  console.log(e);
  console.log('I am' + name);
};

<button onClick={(e) => handleOnClick("Gia", e)}>button</button>

 

아래와 같이 작성할 수도 있다.

const handleOnClick = name => e => {
  console.log(e);
  console.log('I am' + name);
};

<button onClick={(e) => handleOnClick("Gia")(e)}>button</button>

먼저 함수 호출부를 살펴보면, handleOnClick('Gia')를 호출하고 event 객체를 매개변수로 전달한다.

 

함수 선언부를 보면, handleOnClick 함수는 name을 인자로 받아 내부 함수를 리턴하는 형태이며,

그 리턴되는 내부 함수는 이벤트 객체를 인자로 받는다. (= 함수커링)

 

함수 커링

함수 커링은 함수를 여러 번 사용하여 각기 다른 인수를 적용하여 새로운 함수를 만드는 기술이다.

커링된 함수는 최종적으로 필요한 인수를 모두 제공하였을 때 결과 값을 반환한다.

 

function add(a) {
  return function(b) {
    return a + b;
  };
}

const add5 = add(5);
console.log(add5(3)); // 8

위의 코드에서 add 함수는 a 값을 받아 다음 함수를 반환한다.

add5 변수는 add 함수를 호출하여 5를 제공하여 a 값이 5인 새로운 함수를 만든다.

add5 함수를 호출할 때 3을 제공하여 8을 반환한다.

 

 

 

 

아래는 함수 바인딩의 기본 예시로 참고해본다.

함수를 직접 정의하는 것과 함수 자체를 전달하는 것의 차이

const App = () => {
    return (
        <div>
            <button onClick={() => { alert('클릭했습니다.') }}>클릭하세요</button>
        </div>
    )
}
const App = () => {
    const handleClick = () => {
        alert("클릭했습니다.");
    }
    return (
        <div>
            <button onClick={handleClick}>클릭하세요</button>
        </div>
    );
};

 

재사용 측면

함수를 직접 정의하는 것은 각 컴포넌트에서 새로운 함수를 생성할 때마다 메모리에 새로운 함수 객체가 생성된다.

함수 자체를 전달하는 경우, 재사용 가능한 함수를 만드는 것으로,

각 컴포넌트에서는 같은 함수 객체를 참조하며, 메모리 관리에 유리하다.

따라서 함수 자체를 전달하는 것이 메모리 관리에 유리하고, 재사용성이 높아지며, 유지보수성이 좋아진다.

 

this

함수를 직접 정의하는 경우에는 this는 각 컴포넌트의 인스턴스를 가리키며,

함수가 정의된 컴포넌트의 상태 등의 데이터에 접근하려면 bind 메소드를 사용하여 this의 범위를 특정 객체로 고정시킬 수 있다.

함수를 전달하는 경우, this는 전달된 함수의 문맥을 가리키며, 함수가 호출될 때 this의 값이 결정된다.

따라서 함수 자체에서 this를 사용하여 데이터에 접근할 수 있다.

 

 

반응형