리액트를 다루는 기술 4장 - 이벤트 핸들링

sh·2022년 8월 2일
0

이벤트 사용할 때 주의사항

  1. 이벤트 이름은 카멜 표기법으로 작성
  2. 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달
  3. DOM 요소에만 이벤트 설정 가능
    div, button, input, form, span 등의 DOM 요소에는 이벤트를 설정할 수 있지만, 직접 만든 컴포넌트에는 이벤트를 자체적으로 설정 불가


클래스형 컴포넌트에서 이벤트 핸들링 구현

임의 메서드 만들기

import React, { Component } from "react";

class EventPractice extends Component {
  state = {
    message: "",
  };

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({
      message: e.target.value,
    });
  }

  handleClick() {
    alert(this.state.message);
    this.setState({
      message: "",
    });
  }

  render() {
    return (
      <div>
        <h1>이벤트 연습</h1>
        <input
          type="text"
          name="message"
          placeholder="아무거나 입력해보세요"
          value={this.state.message}
          onChange={this.handleChange}
        />
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }
}

export default EventPractice;

함수가 호출될 때 this는 호출부에 따라 결정되므로, 클래스의 임의 메서드가 특정 HTML 요소의 이벤트로 등록되는 과정에서 메서드와 this의 관계가 끊어져 버린다.
이 때문에 임의 메서드가 이벤트로 등록되어도 this를 컴포넌트 자신으로 제대로 가리키기 위해서는 메서드를 this와 바인딩하는 작업이 필요하다.

Property Initializer Syntax를 사용한 메서드 작성

메서드 바인딩은 생성자 메서드에서 하는 것이 정석 but 새 메서드를 만들 때마다 생성자도 수정해야 한다. 이 방법을 더 간단하게 하기 위해 바벨의 transform-class-properties 문법을 사용해 화살표 함수 형태로 메서드를 정의한다.

handleChange = (e) => {
   this.setState({
      message: e.target.value,
    });
}

handleClick = () => {
	alert(this.state.message);
    this.setState({
      message: "",
    });
}

input 여러 개 다루기

event 객체를 활용한다. onChange 이벤트 핸들러에서 e.target.name 은 해당 인풋의 name을 가리킨다.

handleChange = e => {
  this.setState({
    [e.target.name]: e.target.value
  });
};

객체 안에서 key를 [ ] 로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이 key값으로 사용된다.


함수형 컴포넌트에서 이벤트 핸들링 구현

import React, { useState } from "react";

const EventPractice = () => {
  const [form, setForm] = useState({
    username: "",
    message: "",
  });

  const { username, message } = form;

  const onChange = (e) => {
    const nextForm = {
      ...form,	//기존의 form 내용 복사
      [e.target.name]: e.target.value, // 원하는 값 덮어 씌우기
    };
    setForm(nextForm);
  };

  const onClick = () => {
    alert(username + ": " + message);
    setForm({
      username: "",
      message: "",
    });
  };

  const onKeyPress = (e) => {
    if (e.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}
        onKeyPress={onKeyPress}
      />
      <button onClick={onClick}>확인</button>
    </div>
  );
};

export default EventPractice;

0개의 댓글