React | 6. 이벤트 핸들링

sojung·2021년 2월 12일
0

React

목록 보기
6/8
post-thumbnail

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

  • 이벤트 이름은 카멜 표기법으로 작성한다.
    • onclick → onClick
  • 이벤트에 실행할 자바스크립트 코드를 전달한 것이 아니라, 함수 형태의 값을 전달한다.
  • DOM 요소에만 이벤트를 설정할 수 있다.
  	<MyComponent onClick={doSomething}/>
  • 하지만 전달받은 props를 컴포넌트 내부의 DOM 이벤트로 설정할 수는 있다.
	<div onClick={this.props.onclick}>
	</div>

이벤트 핸들링

1. 컴포넌트 생성 및 불러오기

//EventPractice.js

import React, { Component } from "react";

class EventPractice extends Component {
  render() {
    return (
      <div>
        <h1>이벤트연습</h1>
      </div>
    );
  }
}

export default EventPractice;
//App.js

import React from "react";
import EventPractice from "./components/EventPractice";

function App() {
  return <EventPractice></EventPractice>;
}

export default App;

2. onChange 이벤트 핸들링하기

onChange 이벤트 설정

//EventPractice.js

import React, { Component } from "react";

class EventPractice extends Component {
  render() {
    return (
      <div>
        <h1>이벤트연습</h1>
        <input
          type="text"
          name="message"
          placeholder="아무거나 입력해 보세요"
          onChange={(e) => {
            console.log(e);
          }}
        ></input>
      </div>
    );
  }
}

export default EventPractice;
  • e 객체는 SyntheticEvent로 웹 브라우저의 네이티브 이벤트를 감싸는 객체이다.
  • 네이티브 이벤트와 인터페이스가 같으므로 순수 자바스크립트에서 HTML 이벤트를 다룰 때와 똑같이 사용하면 된다.
  • SyntheticEvent 및 네이티브 이벤트와 달리 이벤트가 끝나고 나면 이벤트가 초기화되므로 정보를 참조할 수 없다. 예를 들어, 0.5초 뒤에 e 객체를 참조하면 e 객체 내부의 모든 값이 비워지게 된다.
  • 비동기적으로 이벤트 객체를 참조할 일이 있다면 e.persist() 함수를 호출해 주어야 한다.
onChange={(e) => {
            console.log(e.target.value);
          }}

인풋 값인 e.target.value 를 콘솔에 기록하였다.

state에 input 값 담기

//EventPractice.js

import React, { Component } from "react";

class EventPractice extends Component {
  state = {
    message: "",
  };
  render() {
    return (
      <div>
        <h1>이벤트연습</h1>
        <input
          type="text"
          name="message"
          placeholder="아무거나 입력해 보세요"
          value={this.state.message}
          onChange={(e) => {
            this.setState({ message: e.target.value });
          }}
        ></input>
      </div>
    );
  }
}

export default EventPractice;

생성자 메서드인 constructor에서 state 초깃값을 설정하고, 이벤트 핸들링 함수 내부에서 this.setState 메서드를 호출하여 state를 업데이트한다.


import React, { Component } from "react";

class EventPractice extends Component {
  state = {
    message: "",
  };
  render() {
    return (
      <div>
        <h1>이벤트연습</h1>
        <input
          type="text"
          name="message"
          placeholder="아무거나 입력해 보세요"
          value={this.state.message}
          onChange={(e) => {
            this.setState({ message: e.target.value });
          }}
        ></input>
        <button
          onClick={() => {
            alert(this.state.message);
            this.setState({ message: "" });
          }}
        >
          확인
        </button>
      </div>
    );
  }
}

export default EventPractice;
  • 클릭 이벤트가 발생하면 현재 message을 띄운다.
  • 이후 input 내부는 공백으로 설정한다.

3. 임의 메서드 만들기

이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달한다.

메서드 이름은 어떻게 정하지?
마음대로 정해도 되지만, 규칙이 있으면 좋다. handle___ 형식으로 정하면 좋다.

import React, { Component } from "react";

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

  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}
        ></input>
        <button onClick={this.handleClick}>확인</button>
      </div>
    );
  }
}

export default EventPractice;

4. input 여러 개 다루기

input이 여러 개일 때는 메서드를 여러 개 만들 수도 있지만, event 객체를 활용할 수도 있다. e.target.name을 사용하자.

import React, { Component } from "react";

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

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

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

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

export default EventPractice;
  • render함수에서 name 값이 username인 input을 렌더링
  • state 쪽에도 username이라는 값을 추가함.
  • 객체 안에서 key를 [ ]로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이 key 값으로 사용된다. 예를 들어, const name = 'Lucy'일 경우, [key]는 Lucy가 된다.
  • e.target.name은 해당 인풋의 name을 가리킨다. 지금은 message하고 username을 가리킨다. 현재 코드에서 name값이 username인 input을 렌더링해 주었고, state쪽에도 username이라는 값을 추가하였다.

5. onKeyPress 이벤트 핸들링

키를 눌렀을 때 발생하는 keyPress 이벤트

import React, { Component } from "react";

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

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

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

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

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

export default EventPractice;

함수형 컴포넌트로 구현해 보기

문자열로 넣기

// EventPratice.js

import React, { useState } from "react";

const EventPracticeFunction = () => {
  const [username, setUsername] = useState("");
  const [message, setMessage] = useState("");
  const onChangeUsername = (e) => setUsername(e.target.value);
  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>
      <input
        type="text"
        name="message"
        placeholder="아무거나 입력해 보세요"
        value={message}
        onChange={onChangeMessage}
        onKeyPress={onKeyPress}
      ></input>
      <button onClick={onClick}>확인</button>
    </div>
  );
};

export default EventPracticeFunction;
  • e.target.name을 활용하지 않고 onChange 관련 함수 두 개를 따로 만들어주었다.
  • 인풋의 개수가 많아지면 e.target.name 을 활용하는 것이 좋다.

객체로 넣기

이해가 어렵다...

import React, { useState } from "react";

const EventPracticeFunction = () => {
  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>
      <input
        type="text"
        name="message"
        placeholder="아무거나 입력해 보세요"
        value={message}
        onChange={onChange}
        onKeyPress={onKeyPress}
      ></input>
      <button onClick={onClick}>확인</button>
    </div>
  );
};

export default EventPracticeFunction;

e.target.name 값을 활용하려면, 위와 같은 useState 를 쓸 때 인풋 값들이 들어 있는 form 객체를 사용해 주면 된다.

profile
걸음마코더

0개의 댓글