공부블로그

리액트 4장. 이벤트 핸들링 본문

리액트/리액트를 다루는 기술

리액트 4장. 이벤트 핸들링

떠어영 2021. 1. 5. 01:09

이벤트( Event ): 사용자가 웹 브라우저에서 DOM요소들과 상호작용하는 것 

 

예를 들어 HTML에서 DOM요소에 이벤트를 설정하는 방법을 살펴보자.

<!DOCTYPE html>
<html>
<head>
  ...
</head>
<body>
  <button onclick="alert('executed')"> 
  //누르면 alert함수를 사용해서 executed문구의 메시지 박스를 띄움
    Click me //이 문구의 버튼을
  </button>
</body>
</html>

HTML에서는 이벤트를 실행하면 " " 사이에 있는 자바스크립트를 실행하도록 작성한다.

 

 

 

4. 1 ) 리액트의 이벤트 시스템

 

 Say. js

import React, { useState } from "react";

const Say = () => {
  const [message, setMessage] = useState(""); //useState의 인자에는 상태의 초기값을 넣어줌
  const onClickEnter = () => setMessage("안녕하세요");
  const onClickLeave = () => setMessage("안녕히 가세요");

  const [color, setColor] = useState("black");

  return (
    <div>
      <button onClick={() => setMessage("안녕하세요")}>입장</button>
      <button onClick={() => setMessage("안녕히 가세요")}>퇴장</button>
      ...

 

1. 이벤트이름은 카멜포기법으로 작성한다.

2. 함수 형태의 객체를 전달한다. ex) onClick={ ( ) => setMessage("안녕히 가세요") }

3. DOM요소에만 이벤트를 설정할 수 있다.

  : 우리가 직접 만든 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다.

   < MyComponent onClick={ doSomething } /> ( X ) 이름이 onClick인 props를 MyComponent에게 전달

   하지만 전달받은 props를 MyComponent컴포넌트 내부의 DOM이벤트로 설정할 수 있다.  

   < div onClick={ this.props.onClick } >

          {      . . .      }

   < /div > ( O ) 

4. 이벤트 종류로는 Touch, Composition, Keyboard, Form, Image, Mouse, Animation, Selection, Transition등이 있다.

 

 


 

4. 2 ) 예제들로 이벤트 핸들링을 익혀보자.

 

App. js

import React from "react";
import EventPractice from "./EventPractice"; //불러와서

const App = () => {
  return <EventPractice />; //태그로 씀
};

export default App;

 

EventPractice. js

import React, { Component } from "react";

class EventPractice extends Component {
  render() {
    return (
      <div>
        <h1>이벤트연습</h1>
        <input
          type="text"
          name="message"
          placeholder="아무거나 입력해보세요"
          onChange={(e) => { //onChange이벤트를 설정!!
            console.log(e);
            console.log(e.target.value); //값이 바뀔때마다 콘솔에 기록
          }}
        />
      </div>
    );
  }
}
export default EventPractice;

 

이번엔 state에 input값을 담아보고 버튼을 눌러 입력값이 state에 들어갔는지 검증해보자.

import React, { Component } from "react";

class EventPractice extends Component {
  state = {
    message: "", //constructor없이 초기값 설정
  };
  render() {
    return (
      <div>
        <h1>이벤트연습</h1>
        <input
          type="text" //입력태그 유형
          name="message" //서버로 전달되는 이름
          placeholder="아무거나 입력해보세요"
          value={this.state.message}  // input의 초기값 = state.message
          onChange={(e) => { // onChange이벤트를 설정!!
            this.setState({               
              message: e.target.value, // state의 message를 input값으로 업데이트
            });
          }}
        />
        <button
          onClick={
            //클릭이벤트가 발생하면 현재comment값(message)을 메시지박스로 띄우고 다시 공백으로 설정
            () => {
              alert(this.state.message);
              this.setState({
                message: "",
              });
            }
          }
        >
          확인
        </button>
      </div>
    );
  }
}
export default EventPractice;

 

 

+ ) 임의 메서드를 만들어 이벤트 핸들링 함수에 전달할 수도 있다.

import React, { Component } from "react";

class EventPractice extends Component {
  state = {
    message: "", //constructor없이 초기값 설정
  };

  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this); 
    // 임의메서드가 이벤트로 등록되는 과정에서 메서드와 this가 끊어지므로
    this.handleClick = this.handleClick.bind(this); // 메서드를 this에 바인딩
  }

  handleChange(e) {
    //임의메서드
    this.setState({
      message: e.target.value,
    });
  }

  handleClick(e) {
    //임의메서드
    alert(this.state.message);
    this.setState({
      message: "",
    });
  }
  render() {
    return (
      <div>
        <h1>이벤트연습</h1>
        <input
          type="text"
          name="message"
          placeholder="아무거나 입력해보세요"
          value={this.state.message} //input의 value = state에 있는 값
          //이거 왜 한거임...?
          onChange={this.handleChange}
        />
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }
}
export default EventPractice;

메서드 바인딩을 할 때는 생성자 메서드에서 하는 것이 정석이지만 화살표 함수 형태로 정의하여 대신할 수도 있다.

위의 코드에서 constructor부분을 지우고 handleChange = ( e ) => { ... } , handleClick = ( ) => { ... } 로 작성한다.

 

 

 

4. 2. 1) input 여러 개 다루기

import React, { Component } from "react";

class EventPractice extends Component {
  state = {
    username: "",
    message: "",
  }; //constructor없이 초기값 설정

  handleChange = (e) => { //임의메서드
    this.setState({
      [e.target.name]: e.target.value, //name이 가리키는 값이 key값
    });
  }

  handleClick = () => { //임의메서드
    alert(this.state.username + ": " + this.state.message);
    this.setState({
      username: "",
      message: "",
    });
  }
  render() {
    return (
      <div>
      <h1>이벤트연습</h1>
      <input
          type="text"
          name="username"
          placeholder="사용자명"
          value={this.state.username} //input의 value = state의 username값
          onChange={this.handleChange} //name이 가리키는 username이 key값
        />
        <input
          type="text"
          name="message"
          placeholder="메시지를 입력하세요."
          value={this.state.mesage} //input의 value = state의 message값
          onChange={this.handleChange} ////name이 가리키는 message가 key값
        />
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }
}
export default EventPractice;

 

위 코드에서 중요한 부분은 [ e. target. name ] : e. target. value 이다.

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

ex) const name = 'variantKey' ;

     const object = { [ name ] : 'value' } ; 라고 작성하면  'variantKey' : 'value' 이다.

 

 

4. 2. 2 ) onKeyPress 이벤트 핸들링

handleKeyPress = (e) => {
    if (e.key === "Enter") {
      //키보드에서 Enter가 눌리면
      this.handleClick(); //메소드 실행
    }
  };

를 추가하고

 

두번째 input태그 안에

onKeyPress={this.handleClick} //onKeyPress 이벤트 핸들링

를 추가한다.

 

 

 

4. 3 ) 함수형 컴포넌트에서의 이벤트 핸들링 

const EventPractice = () => { //함수형 컴포넌트

  const [username, setUsername] = useState(""); //각각 state 값이랑 set함수
  const [message, setMessage] = useState("");

  const onChangeUsername = (e) => setUsername(e.target.value); //입력값을 set함수의 인자로 받음
  const onChangeMessage = (e) => setMessage(e.target.value);

  const onClick = () => {
    alert(username + ": " + message);
    setUsername("");
    setMessage("");
  };

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

export default EventPractice;

 

 

4. 3. 1 ) useState를 통해 객체를 넣어보고 e. target. name 을 활용해 input값을 여러개 받아보자.

import React, { useState } from "react";

const EventPractice = () => {
  //함수형 컴포넌트
  const [form, setForm] = useState({
    username: "",
    message: "",
  });

  const { username, message } = form; //form 객체

  const onChange = (e) => {
    const nextForm = {
      ...form, //기존의 form 내용을 이 자리에 복사한 뒤
      [e.target.name]: e.target.value, // 원하는 값을 덮어 씌우기 (key값은 name이 가리키는 값)
    };
    setForm(nextForm); // 위에서 선언한 객체를 인자로 setForm함수 실행
  };

  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} //name = username이므로 username = 입력값, nextForm을 받은 setForm실행
      />
      <input
        type="text"
        name="message"
        placeholder="메시지를 입력하세요."
        value={message}
        onChange={onChange} //name = message이므로 message = 입력값, nextForm을 받은 setForm실행
        onKeyPress={onKeyPress}
      />
      <button onClick={onClick}>확인</button>
    </div>
  );
};

export default EventPractice;

 

 

이번장에서는 이벤트 핸들링에 대해서 알아보았다. 리액트에서의 이벤트는 순수 javascript와 jQuery를 사용한 웹을 다루는 것과 비슷하다.