JavaScript/React

React의 이벤트 처리

Loko 2021. 8. 8. 21:02

React의 이벤트 처리 방식은 DOM의 이벤트 처리 방식과 유사하다.
단, 몇 가지 문법에서의 차이가 있다.

  • React에서 이벤트는 소문자 대신 camelCase를 사용한다.
  • JSX를 사용하여 문자열이 아닌 함수로 이벤트 처리 함수를 전달한다.

이러한 차이점을 뚜렷하게 표현하자면 다음과 같다.

//HTML의 이벤트 처리 방식
<button onclick="handleEvent()">Event</button>

//React의 이벤트 처리 방식
<button onClick={handleEvent}>Event</button>

 

onChange

input, textarea, select와 같은 Form 엘리먼트는 사용자의 입력값을 제어하는 데 사용된다.
React에서는 이러한 변경될 수 있는 입력값을 일반적으로 컴포넌트의 state로 관리하고 업데이트한다.
onChange 이벤트가 발생하면 e.target.value를 통해 이벤트 객체에 담겨있는 input 값을 읽어올 수 있다.
이렇게 불러온 값을 setState를 통해 새로운 state로 갱신한다.

 

onClick

사용자가 클릭을 했을 때 발생하는 이벤트이다.
button이나 a 태그와 같이 주로 사용자의 행동에 따라 애플리케이션이 반응해야 할 때 자주 사용하는 이벤트이다.
다음은 input 창에 이름을 입력하고 버튼을 누를 경우 입력한 이름을 alert 창으로 띄우는 예제이다.

function NameForm() {
  const [name, setName] = useState("");

  const handleChange = (e) => {
    setName(e.target.value);
  };

  return (
    <div>
      <input type="text" value={name} onChange={handleChange}></input>
      <button onClick={alert(name)}>Button</button>
      <h1>{name}</h1>
    </div>
  );
}

위와 같이 onClick 이벤트에 alert(name) 함수를 바로 호출하면 컴포넌트가 렌더링될 때 함수 자체가 아닌 함수 호출의 결과가 onClick에 적용된다.
때문에 버튼을 클릭할 때가 아닌, 컴포넌트가 렌더링될 때에 alert이 실행되고 따라서 그 결과인 undefined가 onClick에 적용되어서 클릭했을 때 아무런 결과도 일어나지 않는다.
따라서 onClick 이벤트에 함수를 전달할 때는 함수를 호출하는 것이 아니라 리턴문 안에서 함수를 정의하거나 리턴문 외부에서 함수를 정의 후 이벤트에 함수 자체를 전달해야 한다.
단, 두가지 방법 모두 arrow function을 활용해야 해당 컴포넌트가 가진 state에 함수들이 접근할 수 있다.

//리턴문 안에서 직접 정의
<button onClick={() => alert(name)}>Button</button>;

//리턴문 외부 함수 활용
const handleClick = () => {
  alert(name);
};

<button onClick={handleClick}>Button</button>;

 

select 태그 예제

import React, { useState } from "react";
import "./styles.css";

function SelectExample() {
  const [choice, setChoice] = useState("apple");

  const fruits = ["apple", "orange", "pineapple", "strawberry", "grape"];
  const options = fruits.map((fruit) => {
    return <option value={fruit}>{fruit}</option>;
  });

  const handleFruit = (event) => {
    setChoice(event.target.value);
  };

  return (
    <div className="App">
      <select onChange={handleFruit}>
        {options}
      </select>
      <h3>You choose "{choice}"</h3>
    </div>
  );
}

export default SelectExample;

 

팝업창 예제

import React, { useState } from "react";
import "./styles.css";

function App() {
  const [showPopup, setShowPopup] = useState(false);

  const togglePopup = () => {
    setShowPopup(!showPopup);
  };

  return (
    <div className="App">
      <h1>Fix me to open Pop Up</h1>
      <button className="open" onClick={togglePopup}>
        Open me
      </button>
      {showPopup ? (
        <div className="popup">
          <div className="popup_inner">
            <h2>Success!</h2>
            <button className="close" onClick={togglePopup}>
              Close me
            </button>
          </div>
        </div>
      ) : null}
    </div>
  );
}

export default App;

 

화살표 함수를 활용해서 input의 value를 복사하는 예제

import "./styles.css";
import React, { useState } from "react";

export default function App() {
  const [username, setUsername] = useState("");
  const [msg, setMsg] = useState("");

  return (
    <div className="App">
      <div>{username}</div>
      <input
        type="text"
        value={username}
        onChange={(event) => setUsername(event.target.value)}
        placeholder="여기는 인풋입니다."
        className="tweetForm__input--username"
      ></input>
      <div>{msg}</div>
      <textarea
        placeholder="여기는 텍스트 영역입니다."
        className="tweetForm__input--message"
        onChange={(event) => setMsg(event.target.value)}
      ></textarea>
    </div>
  );
}