본문 바로가기
React

[React를 다루는 기술 정리] 4장 이벤트 핸들링

by 치범 2022. 2. 15.

4장 이벤트 핸들링

4.1 리액트의 이벤트 시스템

 

4.1.1 이벤트를 사용할 때 주의 사항

  1. 이벤트 이름은 카멜 표기법으로 작성
  2. 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달합니다.
  3. DOM 요소에만 이벤트를 설정할 수 있습니다.

4.2.3 임의 메서드 만들기

 

4.2.3.1 기본 방식

import React, { Component } from "react";

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

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

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

  handleClick() {
    alert(this.state.name);
    this.setState({ name: "" });
  }
  render() {
    return (
      <div>
        <input
          type="text"
          name="name"
          value={this.state.name}
          onChange={this.handleChange}
        />
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }
}

export default EventPractice;

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

 

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

⁉️ 메서드 바인딩은 생성자 메서드에서 하는것이 정석입니다. 하지만 이 작업을 불편하다고 느낄 수 도 있습니다.

메서드를 만들때마다 생성자에 바인딩을 해주어야 하기 때문인데요.

이 작업을 좀 더 간단하게 하는 방법이 있습니다. 바벨의 transfrom-class-properties 문법을 사용하여 화살표 함수 형태로 메서드를 정의하는 것입니다.

import React, { Component } from "react";

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

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

  handleClick= () => {
    alert(this.state.name);
    this.setState({ name: "" });
  }
  render() {
    return (
      <div>
        <input
          type="text"
          name="name"
          value={this.state.name}
          onChange={this.handleChange}
        />
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }
}

export default EventPractice;

 

4.2.4 input 여러 개 다루기

import React, { Component } from "react";

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

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

  handleClick = (e) => {
    alert(`${this.state.name}님, ${this.state.message}.`);
    console.log(e);
  };
  render() {
    return (
      <div>
        <input
          type="text"
          name="name"
          value={this.state.name}
          onChange={this.handleChange}
        />
        <input
          type="text"
          name="message"
          value={this.state.message}
          onChange={this.handleChange}
        />
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }
}

export default EventPractice;

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

 

4.2.5 onKeyPress 이벤트 핸들링

import React, { Component } from "react";

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

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

  handleClick = (e) => {
    alert(`${this.state.name}님, ${this.state.message}.`);
    console.log(e);
  };

  handleKeyPress = (e) => {
    if (e.key === "Enter") {
      this.handleClick();
    }
  };

  render() {
    return (
      <div>
        <input
          type="text"
          name="name"
          value={this.state.name}
          onChange={this.handleChange}
        />
        <input
          type="text"
          name="message"
          value={this.state.message}
          onChange={this.handleChange}
          onKeyPress={this.handleKeyPress}
        />
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }
}

export default EventPractice;

 

4.3 함수형 컴포넌트로 구현하기

import React, { useState } from "react";

export default function EventPractice() {
  const [form, setForm] = useState({
    name: "",
    message: "",
  });

  const onChange = (e) => {
    const newForm = {
      ...form, // 기존의 
      [e.target.name]: e.target.value,
    };
    setForm(newForm);
  };

  const onClick = () => {
    alert(`${form.name}, ${form.message}.`);
    setForm({ name: "", message: "" });
  };

  const onKeyPress = (e) => {
    if (e.key === "Enter") {
      onClick();
    }
  };
  return (
    <div>
      <input
        name="name"
        value={form.name}
        placeholder="name"
        onChange={onChange}
      />
      <input
        name="message"
        value={form.message}
        placeholder="message"
        onChange={onChange}
        onKeyPress={onKeyPress}
      />
      <button onClick={onClick}>확인</button>
    </div>
  );
}

댓글