본문 바로가기

항해99 스터디/리액트

이벤트 핸들링

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를 알고 있다면 리액트의 컴포넌트 이벤트도 쉽게 다룰 수 있을 것입니다.

'항해99 스터디 > 리액트' 카테고리의 다른 글

컴포넌트 반복  (1) 2024.01.06