FrontEnd :-)

Event Listener 본문

항해99_7기/3주차 React 입문 주차

Event Listener

code10 2022. 5. 23. 19:58

3주 차 팀 과제 문제 하나, 

event listener는 등록되면 반드시 해제되어야 합니다. 클래스형 컴포넌트에서는 컴포넌트가 화면에서 사라질 때(unmount 될 때) event listener를 해제합니다. (componentWillUnmount에서요!) 그럼 라이프사이클 메소드를 사용할 수 없는 함수형 컴포넌트에서는 event listener를 해제할 때 어떻게 해야 할까요?

 

간결한 답

함수형 컴포넌트에서는

useEffect() 훅을 이용한다면 return 구문에서 removeEventListener()를 이용한다.

(useEffect() 훅은 클래스 컴포넌트에서 componentDidMount와 componentDidUpdate, componentWillUnmount 역할을 함)

  React.useEffect(() => {
    // componentDidMount, componentDidUpdate일 때 동작하는 부분이 여기예요.
    text.current.addEventListener("mouseover", hoverEvent);
    
    return () => {
     // 여기가 clean up 부분입니다.
     // componentWillUnmount 때 동작하는 부분이 여기예요.
        text.current.removeEventListener("mouseover", hoverEvent);
    };
  }, [text]);

 

removeEventListener() 구문

DOM객체. removeEventListener(이벤트명, 실행했던 함수명);

 

 


문제 분석 및 의문

event listener는 등록되면 반드시 해제되어야 합니다.  

=> event listener는 무엇인가? ---1️⃣

=> 왜 반드시 해제되어야 하나? ---2️⃣

클래스형 컴포넌트에서는 컴포넌트가 화면에서 사라질 때(unmount 될 때) event listener를 해제합니다. (componentWillUnmount에서요!) 그럼 라이프사이클 메소드를 사용할 없는 함수형 컴포넌트에서는 event listener 해제할 어떻게해야 할까요?

=> 왜 라이프사이클 메소드에서 함수형 컴포넌트를 사용할 수 없나? ---3️⃣

=> 함수형 컴포넌트에서 event listener를 해제하는 방법은? ---4️⃣

 

1️⃣ event listener는 무엇인가?

=> 특정 DOM에서 (자바스크립트) 이벤트가 발생할 때, 특정 함수를 호출해 처리하는  것.

=> 즉, 사용자가 어떤 행동(=이벤트)을 하는지 안 하는지 지켜보다가 알려주는 것.

=> 이벤트 리스너를 이용하면 특정 스크롤 이벤트 발생 시 이벤트 실행 혹은 input 태그에 글자 수를 확인하는 등으로 활용 가능.

=> 자주 쓰이는 이벤트 ↓

  • 포커스 이벤트(focus, blur)
  • 폼 이벤트(reset, submit)
  • 뷰 이벤트(scroll, resize)
  • 키보드 이벤트(keydown, keyup)
  • 마우스 이벤트(mouseenter, mouseover, click, dbclick, mouseleave)
  • 드래그 앤 드롭 이벤트 (dragstart, drag, dragleave, drop)

=> 이벤트 리스너와 이벤트 핸들러(event handler)를 합쳐 이벤트 리스너라고도 함. ↓

더보기

각각의 이용 가능한 이벤트들은 이벤트 핸들러(event handler)를 가지고 있는데, 이는 이벤트가 발생되면 실행되는 코드 블록 (보통 여러분과 같은 프로그래머가 만드는 JavaScript 함수)입니다. 그러한 코드 블록이 이벤트에 응답해서 실행되기 위해 정의되었을 때, 우리는 이벤트 핸들러를 등록(register)했다고 말합니다. 알림: 이벤트 핸들러는 때때로 이벤트 리스너(event listener)라고 불립니다 — 이것들은 우리의 목적을 위해 꽤 교체할 수 있지만, 그러나 엄밀히 말하자면, 그들은 같이 동작합니다. 리스너는 발생되는 이벤트에 대해 듣고, 핸들러는 발생되는 이벤트에 응답해서 실행되는 코드입니다. (mdn)

 

이벤트 핸들러: 이벤트가 발생했을 때 그 처리를 담당하는 실행 함수.

이벤트 리스너: 특정한 이벤트에 대해서 일어날 동작 정의. 

이벤트 이벤트 리스너(이벤트 속성) 이벤트 핸들러
click onclick function(){}

=> 이벤트 핸들러가 연결된 특정 요소에서 지정된 타입의 이벤트가 발생하면, 웹 브라우저는 이벤트 리스너에 연결된 이벤트 핸들러를 실행. 

=> 등록 방법

1. 객체나 요소에 프로퍼티로 등록하는 방법

- 이벤트 대상이 되는 객체나 요소에 프로퍼티로 등록한 이벤트 리스너가 가장 먼저 호출.

 

2. 객체나 요소의 메소드로 이벤트 리스너를 전달하는 방법

- addEventListener() 메소드를 사용하여 등록한 이벤트 리스너를 등록한 순서대로 호출.

 

2️⃣ 왜 반드시 해제되어야 하나?

이벤트가 발생되어 상태가 변하면 그 상태를 계속 유지하기 때문. 

변경 상태가 유지되어도 상관없나?

그러나, 비록 눈에 보이진 않아도 같은 이벤트(행동)가 일어났을 때 계속 실행되어 메모리 누수의 원인이 될 수 있다!!

이벤트 리스너는 반드시 해제하자.

+특정 페이지에서만 사용하는 이벤트 리스너라면 해당 페이지를 떠날 때 이벤트 리스너를 삭제해준다.

 

3️⃣ 왜 라이프사이클 메소드에서 함수형 컴포넌트를 사용할 수 없나?

 

라이프 사이클 메소드는 클래스형 컴포넌트에서만 사용할 수 있기 때문.

 

라이프 사이클 메소드란?

=> 컴포넌트 클래스에서 특별한 메소드를 선언하여 컴포넌트가 마운트되거나 언마운트 될 때 일부 코드를 작동하는 것. 

(https://ko.reactjs.org/docs/state-and-lifecycle.html#gatsby-focus-wrapper)


(비교) 클래스형 컴포넌트에서 event listener 구독하기

(1) 어떤 행동(=이벤트 발생!) 뒤에 실행할 함수 먼저 만들어요.
(2) 이제 addEventListener()를 이용해서 이벤트를 등록합니다.
(3) 이벤트는 꼭 컴포넌트가 사라지면 지워주세요!

hoverEvent = (e) => {
    // 콘솔로 이 이벤트가 누구에게서 일어났는 지 확인할 수 있습니다.
    console.log(e.target);
    // ref랑 같은 녀석인 지 확인해봐요!
    console.log(this.circle.current);

    this.circle.current.style.background = "yellow";
  }

 // 발생
componentDidMount(){
    // 리액트 요소가 잘 잡혔나 확인해봅시다!
    console.log(this.circle);

    // 마우스를 올렸을 때, 이벤트가 일어나는 지 확인해봅시다.
    this.circle.current.addEventListener("mouseover", this.hoverEvent);
  }
  
  //삭제
componentWillUnmount() {
    this.circle.current.removeEventListener("mouseover", this.hoverEvent);
  }

4️⃣ 함수형 컴포넌트에서 event listener를 해제하는 방법은?

 

함수형 컴포넌트에서 event listener 구독하기

(1) useEffect() : 리액트 훅

- 라이프 사이클 함수 중 componentDidMount와 componentDidUpdate, componentWillUnmount를 합쳐둔 것.

(2) 어떤 행동(=이벤트 발생!) 뒤에 실행할 함수 먼저 만들어요.

(3) 이제 addEventListener()를 이용해서 이벤트를 등록합니다.

(4) 이벤트는 꼭 컴포넌트가 사라지면 지워주세요!

- useEffect에서 clean up은 return 구문을 이용!

// 첫번째 인자는 익숙하죠! 화살표 함수! 넵, 렌더링 시 실행할 함수가 여기에 들어갑니다.
  // 두번째 인자의 []! 디펜던시 어레이라고 불러요. 여기 넣어준 값이 변하면 첫번째 인자인 콜백함수를 실행합니다.
  React.useEffect(() => {
    // 여기가 rendering 때 실행될 구문이 들어가는 부분입니다.
    // componentDidMount, componentDidUpdate일 때 동작하는 부분이 여기예요.
    text.current.addEventListener("mouseover", hoverEvent);
    
    return () => {
        // 여기가 clean up 부분입니다.
        // componentWillUnmount 때 동작하는 부분이 여기예요.
        text.current.removeEventListener("mouseover", hoverEvent);
    };
  }, [text]);

 

 

(참고)

https://ko.reactjs.org/docs/state-and-lifecycle.html#gatsby-focus-wrapper

https://ordinary-code.tistory.com/64

https://codedragon.tistory.com/5743

https://developer.mozilla.org/ko/docs/Learn/JavaScript/Building_blocks/Events

Comments