본문 바로가기

React

이벤트 핸들링(Event Handling)

✅ 1. 이벤트 핸들링(Event Handling)이란?



 사용자가 웹 브라우저에서 DOM 요소들과 상호 작용하는 것을 이벤트(event)라고 합니다.예를 들어 버튼에 마우스 커서를 올렸을 때는 onmouseover 이벤트를 실행, 클릭했을 때는 onclick 이벤틀를 실행, Form 요소는 값일 바뀔 때 onchange 이벤트를 실행합니다.리액트에서의 이벤트 시스템은 이러한 HTML에서 DOM요소에 이벤트를 설정하는 방법과 매우 유사합니다.그럼 한번 살펴 봅시다.

✅  2. 리액트의 이벤트 시스템
리액트의 이벤트 시스템은 웹 브라우저의 HTML 이벤트와 인터페이스가 동일하기 때문에 사용법이 꽤 비슷합니다.아래에서 살펴 봅시다.

import React, { useState } from "react";

function App() {
  const [message, setMessage] = useState("");
  const onClickEnter = () => {
    setMessage("안녕하세요!");
  };
  const onClickLeave = () => {
    setMessage("안녕히 가세요!");
  };
  const [color, setColor] = useState("black");
  return (
    <div>
      <button onClick={onClickEnter}>입장</button>
      <button onClick={onClickLeave}>퇴장</button>
    </div>
    (...)
  );
}

export default App;



✅  3.  이벤트를 사용할 때 주의 사항
1) 이벤트 이름은 카멜 표기법으로 작성합니다.
  Ex ) onclick => onClick , onkeyup => onKeyUp
2) 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달합니다.
   HTML에서 이벤트를 설정할 때는 큰따옴표 안에 실행할 코드를 넣었지만, 리액트에서는 함수 형태의 객체를 전달해야 합니다.
3.) DOM 요소에만 이벤트를 설정할 수 있습니다.
  즉 div, button, input, form, span 등의 DOM 요소에는 이벤트를 설정할 수 있지만, 우리가 직접 만든 컴포넌트에는 이벤트를 자체적으로 설정할 수 없습니다.

Ex ) <MyComponent onClick={doSomething} /> ==> X ,  <div onClick={this.props.onClick}>{ /* (...) */ } </div> ==> O


✅  4. 이벤트 종류
 리액트에서 지원하는 이벤트 종류는 다음과 같습니다.

Clipboard
Touch
Compositon
UI
Keyboard
Wheel
Focus
Media
Form
Image
Mouse
Animation
Selection
Transition



✅  5. onClick, onChange, onKeyPress
 위에서 볼 수 있는것과 같이 이벤트에는 많은 종류가 있지만 본문에서는 위의 대표적인 이벤트만 다뤄 보겠습니다.
1) useState + onClick

우리가 어떤 버튼을 만들고 그것을 클릭했을 때 state를 변경하는 것을 만들어 볼게요.

먼저 버튼을 만들어볼까요? <button> 태그를 이용해서 버튼을 생성합니다.

// src/App.js

import React from "react";

function App() {

  return (
    <div>
      <button>버튼</button>
    </div>
  );
}

export default App;


버튼은 누르라고 있는 것이죠!

우리는 이 버튼을 눌렀을 때 하고 싶은 행동을 함수로 만들 수 있습니다. 아래 코드와 같이 onClickHandler 라는 함수를 만들고 onClick={} 에 넣어주었습니다. React에서는 이러한 방식으로 함수와 컴포넌트(button 태그)를 연결시킵니다.

우리는 이 함수를 이벤트 핸들러 라고 표현합니다. 함수에 console.log("hello button"); 라는 코드를 작성하고 버튼을 누른 후 콘솔을 봅시다. 우리가 만든 함수로 인해 버튼을 누를 때 마다 콘솔에 hello button 이 찍히는 것이 보입니다.

import React from "react";

function App() {
  // 버튼을 눌렀을 때 하고 싶은 행동 
  function onClickHandler() {
    console.log("hello button");
  }
  return (
    <div>
      <button onClick={onClickHandler}>버튼</button>
    </div>
  );
}

export default App;



✅  1-2) state 구현하고 이벤트 핸들러와 연결하기

우선 state를 하나 만듭니다. 그리고 이 버튼을 클릭을 했을 때 state 값을 바꿔보겠습니다. 이벤트 핸들러를 만들어주고 그 안에 setName 을 넣어줍니다.

이제 우리가 버튼을 누르면 setName()안에 있는 값이 “누렁이”니까, state가 “길동이"에서 “누렁이”로 바뀌겠군요!

import React, { useState } from "react";

function App() {
  const [name, setName] = useState("길동이");

  function onClickHandler() {
    setName("누렁이");
  }

  return (
    <div>
      {name}
      <button onClick={onClickHandler}>버튼</button>
    </div>
  );
}

export default App;


✅  2) useState + onChange

input에서는 보통 사용자가 입력한 값을 state로 관리하는 패턴을 많이 사용합니다. 아래 코드를 봐주세요.

import React, { useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  return (
    <div>
      <input type="text" />
    </div>
  );
};



export default App;
input과 useState를 사용해서 input의 값을 넣을 value라는 state를 생성했습니다. 이번에는 function keyword를 사용하지 않고 화살표 함수를 사용해보았어요.

✅  2-1) 이벤트핸들러를 구현하고 state와 연결하기

input과 생성한 state(value)를 연결해볼게요.

먼저 input에 onChange라는 이벤트를 불러내고, 우리가 생성한 이벤트 핸들러 함수를 넣습니다. 함수는 아래 코드 처럼 작성합니다.

import React, { useState } from "react";

const App = () => {
  const [value, setValue] = useState("");

  const onChangeHandler = (event) => {
    const inputValue = event.target.value;
    setValue(inputValue);
  };

console.log(value) // value가 어떻게 변하는지 한번 콘솔로 볼까요?

  return (
    <div>
      <input type="text" onChange={onChangeHandler} value={value} />
    </div>
  );
};

export default App;



그리고 우리는 이벤트 핸들러 안에서 자바스크립트의 event 객체를 꺼내 사용할 수 있습니다. 사용자가 입력한 input의 값은 event.target.value 로 꺼내 사용할 수 있죠. 마지막으로 state인 value를 input의 attribute인 value에 넣어주면 input과 state 연결하기, 끝 입니다!


✅  3) onKeyUp

이번에는 키를 눌렀을 때 발생하는 keyUp 이벤트를 처리하는 방법을 알아보겠습니다. 인풋에서 Enter를 눌렀을 때 handleClick 메서드를 호출하도록 코드를 작성해 봅시다.

import React, { useState } from "react";

function App() {
  const [username, setUsername] = useState("");
  const [message, setMessage] = useState("");
  const onChangeUsername = (event) => {
    setUsername(event.target.value);
  };
  const onChangeMessage = (event) => {
    setMessage(event.target.value);
  };
  const onClick = () => {
    alert(username + ": " + message);
    setUsername("");
    setMessage("");
  };
  const onKeyPress = (event) => {
    if (event.key === "Enter") {
      onClick();
    }
  };
  return (
    <div>
      <h1>이벤트 연습</h1>
      <input
        type="text"
        name="username"
        placeholder="사용자명"
        value={username}
        onChange={onChangeUsername}
      />
      <input
        type="text"
        name="message"
        placeholder="아무거나 입력해 보세요"
        value={message}
        onChange={onChangeMessage}
        onKeyUp={onKeyPress}
      />
      <button onClick={onClick}>확인</button>
    </div>
  );
}

export default App;


✅  두 번째 텍스트 인풋에서 텍스트를 입력하고 Enter key를 누르면 onClick 메서드가 실행되며 인풋값이 입력됩니다.

✅  6. input 여러 개 다루기
 우리는 input 값을 state에 넣는 방법을 배웠습니다. 하지만 input이 여러 개일 때는 어떻게 작업할까요? 메서드를 여러 개 만들어야 할까요? 물론 그것도 하나의 해법이기는 합니다만, 더 쉽게 처리하는 방법이 있습니다.

바로 event 객체를 활용하는 것입니다. e.target.name 값을 사용하면 됩니다. onChange 이벤트 핸들러에서 e.target.name은 해당 인풋의 name을 가리킵니다. 지금은 message 겠죠? 이 값을 사용하여 state를 설정하면 쉽게 해결할 수 있습니다.
코드를 한번 살펴봅시다.

function App() {
  const [form, setForm] = useState({
    username: "",
    message: "",
  });
  const { username, message } = form;
  const onChange = (event) => {
    const nextForm = {
      ...form, // 기존의 form 내용을 이 자리에 복사한 뒤
      [event.target.name]: event.target.value, // 원하는 값을 덮어 씌우기
    };
    setForm(nextForm);
  };
  const onClick = () => {
    alert(username + ": " + message);
    setForm({
      username: "",
      message: "",
    });
  };
  const onKeyUp = (event) => {
    if (event.key === "Enter") {
      onClick();
    }
  };
  return (
    <div>
      <h1>이벤트 연습</h1>
      <input
        type="text"
        name="username"
        placeholder="사용자명"
        value={username}
        onChange={onChange}
      />
      <input
        type="text"
        name="message"
        placeholder="아무거나 입력해 보세요"
        value={message}
        onChange={onChange}
        onKeyUp={onKeyUp}
      />
      <button onClick={onClick}>확인</button>
    </div>
  );
}

export default App;


✅  event.target.name 값을 활용하려면, 위와 같이 uesState를 쓸 때 인풋 값들이 들어 있는 form 객체를 사용해 주면 됩니다.



✅  7.  정리
리액트에서 이벤트를 다루는 것은 순수 자바스크립트 또는 jQuery를 사용한 웹 애플리케이션에서 다루는 것과 비슷합니다. 리액트의 장점 중 하나는 자바스크립트에 익숙하다면 쉽게 활용할 수 있다는 것입니다. 따라서 기존 HTML DOM Event를 알고 있다면 리액트의 컴포넌트 이벤트도 쉽게 다룰 수 있을 것입니다.

[출처] https://codenamedev.tistory.com/2