본문 바로가기
리엑트/실무 중심 FE 입문자를 위한 React

05 이벤트 헨들링

by 문자메일 2024. 8. 14.

 

5-1 이벤트 연결하기

 

JSX에서 함수 연결하기


## 리액트의 컴포넌트는 상태를 가지고 그 상태의 변화에 따라서 컴포넌트가 리렌더링 된다.

그 말은 리엑트 컴포넌트의 상태에 변화를 주는 무언가가 있다는 것

그 무언가의 대부분이 대부분 이벤트 이다.

 

JSX에서 camelCase 형태의 속성에 함수를 전달

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

 

아래 예시 이미지처럼 리액트에서 이벤트를 바인딩을 하게 되면, 해당하는 이벤트가 발생이 됐을 때 해당 함수에 클릭에 대한 이벤트 객체를 넘겨주게 된다. 함수에서는 인자로 받는다.

이벤트 객체 로깅 확인된 것

 

 

 

아래는 리엑트로 이벤트 등록하는 것이 아닌, 자바스크립트로 이벤트 등록하는 스크립트

document.body.addEventListener('click', (e) => {console.log(e)});

 

자바스크립트에서 전달해주는 이벤트를 진짜 이벤트 객체라고 한다면, 리엑트에서 연결하고 받게 되는 이벤트 객체는 합성 이벤트라고 해서 진짜 이벤트 객체를 원본으로 해서 확장한 이벤트 객체이다.

 

 

추가정보

 /**
   * ℹ️합성 이벤트 (SyntheticEvent)
   * - React에서 이벤트가 발생할 때, 이벤트 핸들러의 인자로 합성 이벤트 객체가 전달됨
   * - 이 합성 이벤트는 javascript 에서 전달 받는 이벤트 객체를 확장(래핑)한 객체임
   *   (거의 동일한 인터페이스를 가지고 있음)
   * - 원본 이벤트 객체(native event)는 syntheticEvent.nativeEvent 에 있음
   * - 지금은 그냥 같은 이벤트 객체라고 생각해도 무방
   */

 

  /**
   * ℹ️이벤트 핸들러(함수)를 만들 때는 react lifecycle을 고려하자!
   *  - 컴포넌트가 리랜더링 되면 컴포넌트 내에서 단순 정의한 함수가 새로운 함수로 만들어짐
   *  - 이것은 불필요한 작업으로 성능 문제를 야기함
   *  - 그래서 함수의 정의를 최대한 컴포넌트 밖으로 빼거나,
   *    useCallback으로 감싸줘서 매 랜더링 마다 새로 만들어지지 않도록 해줄 필요가 있음
   */

 

 

 

 

5-2 이벤트 종류

function App() {
  return (
    <div className="App">
      <button
        onClick={() => {
          console.log("onClick");
        }}
        onMouseDown={() => {
          console.log("onMouseDown");
        }}
        onMouseUp={() => {
          console.log("onMouseUp");
        }}
      >
        Button
      </button>
      <div
        className="box"
        onClick={() => {
          console.log("onClick");
        }}
        onMouseEnter={() => {
          console.log("onMouseEnter");
        }}
        onMouseLeave={() => {
          console.log("onMouseLeave");
        }}
        onMouseMove={() => {
          console.log("onMouseMove");
        }}
      ></div>
      <div>
        <input
          type="text"
          onKeyDown={() => {
            console.log("onKeyDown");
          }}
          onKeyUp={() => {
            console.log("onKeyUp");
          }}
          onKeyPress={() => {
            console.log("onKeyPress");
          }}
          onFocus={() => {
            console.log("onFocus");
          }}
          onBlur={() => {
            console.log("onBlur");
          }}
          onChange={() => {
            console.log("onChange");
          }}
        />
      </div>
    </div>
  );
}

export default App;

 

 

5-3 Form

Controlled Component (제어 컴포넌트) 라는 개념

React에 의해 입력 요소의 값이 제어되는 컴포넌트

 

장점

- 컴포넌트의 state와 input value가 완전히 동일한 값을 갖음

- 다른 컴포넌트에 input value를 전달하거나 다른 이벤트 핸들러에서 값을 재설정 할 수 있음

 

단점

- 값이 변경되는 매 순간 렌더링이 된다. (해당 컴포넌트의 영향 범위가 클 수록 성능 저하)

 

컴포넌트의 state와 form 요소가 연결된 컴포넌트를 Controlled 컴포넌트 라고 한다.

 

 

 

 

5-4 설문조사 만들기

 

App.js

import { useState } from "react";
import TextInput from "./components/TextInput";
import Select from "./components/Select";

const contryOptions = ["한국", "중국", "일본", "러시아", "미국"];

function App() {
  const [formValue, setFormValue] = useState({
    name: "",
    contry: "",
    address: "",
  });

  console.log("[App]", formValue);

  return (
    <div className="App">
      <div className="form">
        <div className="form-item">
          <h1>1. 이름이 무엇인가요?</h1>
          <TextInput
            value={formValue.name}
            setValue={(value) => {
              setFormValue((state) => ({
                ...state,
                name: value,
              }));
            }}
          />
        </div>
        <div className="form-item">
          <h1>2. 사는 곳은 어딘가요?</h1>
          <Select
            value={formValue.contry}
            setValue={(value) => {
              setFormValue((state) => ({
                ...state,
                contry: value,
              }));
            }}
            options={contryOptions}
          />
        </div>
        {formValue.contry === "한국" ? (
          <div className="form-item">
            <h1>2-1. 한국 어디에 사나요?</h1>
            <TextInput
              value={formValue.address}
              setValue={(value) => {
                setFormValue((state) => ({
                  ...state,
                  address: value,
                }));
              }}
            />
          </div>
        ) : null}

        <div className="button-group">
          <button
            onClick={() => {
              alert("저장되었습니다.");
              setFormValue({
                name: "",
                contry: "",
                address: "",
              });
            }}
            disabled={formValue.name === "" || formValue.contry === ""}
          >
            저장
          </button>
        </div>
      </div>
    </div>
  );
}

export default App;

 

Select.js

import { useState } from "react";

function Select({ value, setValue, options = [] }) {
  return (
    <select
      value={value}
      onChange={(e) => {
        setValue(e.target.value);
      }}
    >
      <option value="" disabled>
        지역을 선택해주세요.
      </option>
      {options.map((item) => (
        <option key={item} value={item}>
          {item}
        </option>
      ))}
    </select>
  );
}

export default Select;

 

TextInput.js

import { useState } from "react";

function TextInput({ value, setValue }) {

  return (
    <input
      type="text"
      value={value}
      onChange={(e) => {
        setValue(e.target.value);
      }}
    />
  );
}

export default TextInput;

'리엑트 > 실무 중심 FE 입문자를 위한 React' 카테고리의 다른 글

07 React 메모장 만들기  (0) 2024.08.16
06 React 환경 설정  (0) 2024.08.15
04 LifeCycle과 Hooks  (0) 2024.08.13
Chapter 03 컴포넌트  (0) 2024.06.13
JSX  (0) 2024.06.10

댓글