1. React의 이벤트란?

React는 HTML의 이벤트 처리 방식을 기반으로 하지만, 약간의 차이가 있다.

  • HTML 이벤트는 DOM 요소에서 발생하며, 속성이 모두 소문자(ex. onclick)이다.
    <button onclick="activeEvent();">
    	Event Button
    </button>
  • React 이벤트CamelCase 스타일로 작성한다.
    예: onClick, onChange, onMouseEnter
  • JSX내부에서 이벤트 함수를 작성하기 때문에 따옴표가 아닌 중괄호로 감싸 작성한다.
    <button onclick={activeEvent}>
    	Event Button
    </button>

여기서 생길 수 있는 의문!

리액트에서는 {} 이렇게 묶어서 사용한다는 것은 알겠는데 () 괄호는 왜 사용하지 않을까?

그 이유 :

  • onClick={activeEvent}: 함수 참조를 전달한다. 클릭 이벤트가 발생했을 때 React가 해당 함수를 실행한다.
  • onClick={activeEvent()}: 함수가 즉시 실행된 결과를 전달한다. 클릭과 상관없이 컴포넌트 렌더링 시점에 함수가 실행되므로 잘못된 동작을 유발할 수 있다.

React는 이벤트에 함수를 호출하는 HTML과 달리 이벤트에 함수를 정의한다.

왜냐하면 React는 렌더링 할 때 모든 컴포넌트의 함수를 실행시켜 컴포넌트 렌더링 시 이벤트가 발생하지 않아도 해당 이벤트 함수가 실행되기 때문이다.

함수명만 작성
<button onClick={이벤트함수명}>Event Button</button>

화살표 함수로 작성
<button onClick={()=>{이벤트함수명()}}>Event Button</button>

이를 방지하기 위해 함수명만 작성하거나, 화살표 함수로 이벤트에 함수를 정의해 이벤트가 발생했을 때만 작성한 이벤트 함수가 실행되도록 한다. 위의 두 예제는 같은 기능을 한다.


2. React 이벤트 처리 시 주의점

  1. CamelCase를 사용:
    HTML과 달리 React에서는 이벤트 이름을 소문자가 아닌 CamelCase로 작성해야 한다.
    ```jsx
    <button onClick={handleClick}>클릭하세요</button> // 올바른 예
    ```
  2. JSX로 이벤트 핸들러 전달:
    JSX 안에서 함수를 이벤트 핸들러로 전달한다.
    ```jsx
    function handleClick() {
      console.log('Button clicked!');
    }
    <button onClick={handleClick}>클릭</button>
    ```
  3. 기본 DOM 요소에만 직접 이벤트 설정 가능:
    사용자 정의 컴포넌트에는 직접 이벤트를 설정할 수 없다. 대신 props를 통해 이벤트 핸들러를 전달해야 한다.
    ```jsx
    function MyButton({ onClick }) {
      return <button onClick={onClick}>내 버튼</button>;
    }
    <MyButton onClick={handleClick} />
    ```

3. React에서의 이벤트 처리 시스템

웹 브라우저의 이벤트 시스템 :

웹 브라우저가 자체적으로 가지고 있는 이벤트 처리 시스템을 말한다.

사용자의 클릭, 키보드 입력, 마우스 이동 등의 상호작용으로 인해 발생하는 이벤트를 처리한다.

이 웹 브라우저의 이벤트 시스템은 브라우저 별로 다르다. 그렇기 때문에 각 브라우저 별로 이벤트를 다르게 지정해야 하는데 React는 이런 부분에 편의성을 위해 SyntheticEvent를 제공한다.

이어서 ⬇️


4. 합성 이벤트 (Synthetic Event)

React는 합성 이벤트(SyntheticEvent)라는 래퍼(Wrapper) 객체를 사용해, 브라우저의 nativeEvnet 이벤트를 감싼다.

이를 통해 모든 브라우저에서 일관된 이벤트 처리가 가능하다.
(Wrapper란 - Wrapper객체란 기본 기능을 감싸는 새로운 기능 )

  • 합성 이벤트의 특징:
    • 브라우저 간의 호환성 문제 해결
    • 성능 최적화
    • 이벤트 풀링(Event Pooling) 사용
  • 예시:
    function handleClick(e) {
      console.log(e.type); // 'click'
      console.log(e.nativeEvent); // 브라우저의 원래 이벤트 객체
    }
    <button onClick={handleClick}>클릭</button>

자세한 이벤트 종류는 React 공식 문서를 참고!


여기까지의 정리

React는 nativeEvnet라는 브라우저의 고유 이벤트를 Wrapping한 SyntheticEvent 객체를 통해 이벤트를 처리한다. 그리고 SyntheticEvent 객체는 event 또는 e라는 축약 형태로 작성하고, 이 객체가 제공하는 다양한 속성과 메서드를 참조한다.


5. nativeEvnet

SyntheticEvent 내에 포함된 원래의 브라우저 이벤트를 가리킨다.

주의 : nativeEvnet는 SyntheticEvent 내에 포함된 원래의 브라우저 이벤트 이지만 SyntheticEvent가 브라우저의 nativeEvnet와 완벽하게 대응되는 것은 아니다.

예를들어 onMouseLeave 이벤트의 event.nativeEvnet는 mouseout 이벤트를 가리킨다.

브라우저의 고유 이벤트인 nativeEvnet를 확인하고 싶다면 event.nativeEvnet attribute(속성)을 이용하면 된다.


6. Attribute(속성) & method(메서드)

더 자세하게 알아보기

  • type - type은 문자열을 반환하는 Attribute로, click이나 onChange와 같이 해당 이벤트의 이벤트 종류를 알 수 있다.
    예제 )
    export default function SyntheticEventAttr() {
      const checkType = (e) => {
        console.log('e.type:', e.type);
      };
    
      return (
        <>
          <button onClick={checkType}>click</button>
          <input type='text' onChange={checkType} />
        </>
      );
    }
  • target - 이벤트가 발생한 DOM요소를 나타낸다. ⬇️
  • currentTarget - 이벤트 핸들러가 연결된 DOM 요소를 나타낸다.⬇️
    예제 )
    export default function SyntheticEventAttr() {
      const checkType = (e) => {
        console.log("e.type:", e.type);
      };
      const checkTargete = (e) => {
        console.log("e.target:", e.target);
      };
    
      const checkCurrentTarget = (e) => {
        console.log("e.currentTarget:", e.currentTarget);
      };
    
      return (
        <>
          <button onClick={checkType}>click</button>
          <input type="text" onChange={checkType} />
          <h3>e.target</h3>
          <button onClick={checkTargete}>
            <span>click</span>
          </button>
    
          <h3>e.currentTarget</h3>
          <button onClick={checkCurrentTarget}>
            <span>click</span>
          </button>
        </>
      );
    }
  • defaultPrevented Attribute와 preventDefault() 메소드 - 각자 기본 이벤트 방지 여부 확인과 이벤트의 기본 행동을 방지하는 기능을 하는 함수이다.
  • stopPropagation() 메소드 - 이벤트의 상위 전파( 이벤트 버블링 ) 를 중단하는 역할을 한다.

7. 클래스형 컴포넌트에서의 이벤트

  • 클래스형 컴포넌트에서는 this를 사용해 이벤트 핸들러에 접근해야 한다.
    class App extends React.Component {
      handleClick() {
        console.log(this);
      }
      render() {
        return <button onClick={this.handleClick.bind(this)}>클릭</button>;
      }
    }
    

this 문제 해결 방법

  1. bind 사용:
    • 이전 방식으로, 생성자에서 이벤트 핸들러를 bind해야 한다.
      constructor() {
        super();
        this.handleClick = this.handleClick.bind(this);
      }
      
  2. 화살표 함수 사용:
    • 화살표 함수를 사용하면 this를 자동으로 바인딩한다.
      handleClick = () => {
        console.log(this);
      };
      

8. 함수형 컴포넌트에서의 이벤트

React의 함수형 컴포넌트는 간결한 이벤트 처리 방식을 제공한다.

  • 함수에 인자가 없는 경우:
    const handleClick = () => {
      console.log('클릭!');
    };
    <button onClick={handleClick}>클릭</button>
    
  • 함수에 인자가 있는 경우:
    const handleClick = (msg) => {
      console.log(msg);
    };
    <button onClick={() => handleClick('안녕하세요')}>클릭</button>
    
profile
킵고잉~

0개의 댓글