[REACT] 이벤트 핸들링 기법

React 이벤트 핸들링의 기본

React에서는 HTML 이벤트 속성을 camelCase(예: onClick)로 작성하며, 함수를 이벤트 핸들러로 전달해 사용자 행동에 반응합니다.

기본 이벤트 핸들러 정의

가장 간단한 이벤트 핸들링은 컴포넌트 내에서 함수를 정의하고 이를 JSX 요소에 연결하는 방식입니다.

export default function ToggleButton() {
  function handleToggle() {
    alert('토글이 전환되었습니다!');
  }

  return (
    <button 
      onClick={handleToggle}
      style={{ padding: '10px', backgroundColor: '#007bff', color: 'white' }}
    >
      토글 버튼
    </button>
  );
}

인라인 이벤트 핸들러 활용

간단한 동작은 인라인으로 작성할 수 있습니다. 화살표 함수를 사용하면 코드가 간결해지며, 즉석에서 로직을 정의할 수 있습니다.

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div style={{ textAlign: 'center', padding: '20px' }}>
      <p>카운트: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        증가
      </button>
    </div>
  );
}

부모에서 자식으로 이벤트 핸들러 전달

부모 컴포넌트가 자식의 동작을 제어해야 할 때, 이벤트 핸들러를 props로 전달하는 패턴이 자주 사용됩니다. 이는 컴포넌트 간 책임을 명확히 분리합니다.

// TaskButton.js
export default function TaskButton({ onTaskClick, taskName }) {
  return (
    <button 
      onClick={onTaskClick}
      style={{ margin: '5px', padding: '8px', backgroundColor: '#28a745', color: 'white' }}
    >
      {taskName}
    </button>
  );
}

// TaskManager.js
import TaskButton from './TaskButton';

export default function TaskManager() {
  function handleAddTask() {
    alert('새로운 작업이 추가되었습니다!');
  }

  function handleClearTasks() {
    alert('모든 작업이 지워졌습니다!');
  }

  return (
    <div style={{ padding: '20px' }}>
      <h2>작업 관리</h2>
      <TaskButton onTaskClick={handleAddTask} taskName="작업 추가" />
      <TaskButton onTaskClick={handleClearTasks} taskName="작업 초기화" />
    </div>
  );
}

이벤트 전파 제어하기

React의 이벤트는 기본적으로 버블링(전파)됩니다. 예를 들어, 자식 요소에서 발생한 클릭 이벤트는 부모 요소로 전파되어 부모의 이벤트 핸들러도 실행됩니다. 이를 제어하려면 이벤트 객체의 stopPropagation() 메서드를 사용합니다.

export default function NestedClick() {
  function handleInnerClick(e) {
    e.stopPropagation();
    alert('내부 버튼 클릭!');
  }

  function handleOuterClick() {
    alert('외부 컨테이너 클릭!');
  }

  return (
    <div 
      onClick={handleOuterClick}
      style={{ padding: '20px', backgroundColor: '#f0f0f0' }}
    >
      <button 
        onClick={handleInnerClick}
        style={{ padding: '10px', backgroundColor: '#ff5722', color: 'white' }}
      >
        내부 버튼
      </button>
    </div>
  );
}

기본 동작 방지하기

일부 브라우저 이벤트는 고유한 기본 동작을 가집니다. 예를 들어, <form> 요소의 submit 이벤트는 기본적으로 페이지를 새로고침합니다. 이런 기본 동작을 막으려면 이벤트 객체의 preventDefault() 메서드를 호출합니다.

이벤트 핸들링 주의사항

함수 참조 주의

onClick={handleClick()}는 즉시 호출되므로, onClick={handleClick}로 참조만 전달합니다.

이벤트 객체 활용

e.target, e.currentTarget 등으로 요소 정보를 얻을 수 있습니다.

성능 최적화

자주 호출되는 핸들러는 useCallback으로 메모이제이션을 해야합니다.

const handleClick = useCallback(() => {
  console.log('클릭');
}, []);