이벤트 리스너(event listener)와 콜백함수(call back function)

손연주·2021년 7월 9일
1

이벤트 기반 프로그래밍

Javascript는 이벤트를 기반으로 동작한다. 이벤트(event)는 어떤 사건을 의미한다. 브라우저에서의 이벤트란 예를 들어 사용자가 버튼을 클릭했을 때, 웹페이지가 로드되었을 때와 같은 것이다.

이벤트가 발생하는 시점이나 순서를 사전에 인지할 수 없으므로, 이벤트가 발생하면 누군가 이를 감지할 수 있어야 하며 그에 대응하는 처리를 호출해 주어야 한다. 따라서 어떤 이벤트가 발생할 때 어떤 작업을 실행할지 미리 등록해 두어야 한다.

이 작업을 '이벤트 리스너(event listener)에 콜백(callback)을 등록한다'고 한다. 이벤트 리스너에 등록된 콜백함수는 이벤트 핸들러(event handler)이다.

  • 이벤트 : click

  • 이벤트 핸들러(event handler) : function (){}

    • 이벤트가 발생했을 때 그 처리를 담당하는 실행 함수
  • 이벤트 리스너(event listener) : onClick

    • 지정된 타입의 이벤트가 발생하면, 이벤트 리스너가 듣고 있다가 이벤트 핸들러를 실행시킨다.

이벤트 처리 방식

1. HTML

<button onclick="handleEvent()">Event</button>
  • 함수를 호출하는 형태

2. React

<button onClick={handleEvent}>Event</button>
  • 함수 자체를 전달
  • React에서 함수를 호출하는 형태로 작성하게되면 렌더링하는 단계에서 함수가 호출되어, onClick에는 함수를 호출한 결과가 담기게 된다. 함수의 반환값이 없다면 undefined가 담기게 된다.

이벤트 리스너와 콜백 함수

모달 구현

버튼을 누르면 모달창이 떠야한다

export const Modal = () => {
  const [isOpen, setIsOpen] = useState(false);

  const openModalHandler = () => {
    // TODO : isOpen의 상태를 변경하는 메소드를 구현합니다.
    setIsOpen(!isOpen)
  };

  return (
   <>
    <ModalBtn onClick={openModalHandler} >
      {isOpen ?  "Opened" : "open Modal"}
       </ModalBtn>
      {isOpen ? <ModalBackdrop ><ModalView>모달 창이 열렸어요</ModalView></ModalBackdrop> : ""}
    </>
  );

onClick(이벤트 리스너)에 이벤트 핸들러(openModalHandler) 함수 자체가 전달되었다. 버튼을 누르면 이벤트 핸들러가 실행된다.

Tab 버튼 구현

버튼을 누르면 해당 Tab으로 이동해야 한다.

const menuArr = [
    { name: 'Tab1', content: 'Tab menu ONE' },
    { name: 'Tab2', content: 'Tab menu TWO' },
    { name: 'Tab3', content: 'Tab menu THREE' },
  ];

const [index, setIndex] = useState(0)
  const selectMenuHandler = (index) => {
  // 선택한 Tab의 인덱스로 바뀌는 함수
    setIndex(index)

  };

  return (
    <>
      <div>
        <TabMenu>
          {menuArr.map((el,idx)=> {    
            return <li onClick={()=>selectMenuHandler(idx)}>{el.name}</li>
         })}
        </TabMenu>
        <Desc>
          {/*현재 선택된 메뉴 따른 content를 표시*/}
          <p>{menuArr[index].content}</p>
        </Desc>
      </div>
    </>
  );

여기선 onClick에 바로 이벤트핸들러를 전달하지 않고 콜백을 거쳐 전달하였다. 왜일까?

콜백과 파라미터의 관계

onClick={selectMenuHandler(idx)} 로 작성하면 함수를 호출하는 형태이다. 따라서 onClick={()=>selectMenuHandler(idx)}로 작성하였다.

Modal 경우와 Tap의 차이점은 전달인자가 있냐 없냐의 차이이다. Modal의 경우 전달인자가 없기에 미리 작성된 함수 자체를 전달했다. Tap의 경우 idx를 전달인자로 함수에 전달하기 위해 콜백함수를 작성한 것이다. 콜백함수를 받지 않아 onClick={이벤트핸들러(인자)}로 작성하게 되면 함수의 호출이 되므로, 버튼을 누를 때마다 함수가 호출된다. 함수가 호출되면 상태 값이 변한다. 리액트는 상태가 변경되면 상태와 관련된 데이터들을 다시 렌더링하기 때문에 이때 렌더가 너무 많이 됐다는 오류가 뜨게 된다.

콜백함수를 작성하는 경우는 함수를 호출하는 형태가 아닌, 함수자체를 넣은 것과 같기 때문에 우선 콜백함수를 넣고, 이벤트 핸들러를 불러온 것이다.

결론은, 함수의 호출이 아닌 함수 자체를 전달해주기 위해서 인자가 있을 때는 콜백함수를 작성해주는 것이다!

출처

profile
할 수 있다는 생각이 정말 나를 할 수 있게 만들어준다.

2개의 댓글

comment-user-thumbnail
2021년 7월 9일

대본 유출 ㄷㄷㄷ

1개의 답글