안 쓰던 블로그
React-이벤트 핸들링(onChange, onClick, input 여러 개, onKeyPress) 본문
이벤트: 유저가 웹 브라우저에서 DOM 요소들과 상호 작용하는 것
예) 버튼에 마우스 커서를 올렸을 때 onmouseover이벤트를 실행하거나, 클릭하면 onclick이벤트를 실행하는 이벤트
리액트의 이벤트는 HTML의 이벤트와 비슷하다
HTML에서 이벤트는 이렇게 구현한다
HTML 실행: https://jsbin.com/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button onclick="alert('executed')">click me</button>
</body>
</html>
리액트 이벤트 시스템
저번에 했던 버튼 코드
<button onClick={()=>{
this.setState({
number: this.state.number+1
})
}
}>더하기</button>
비슷한 구조를 가지고 있다
주의 사항만 몇 가지 지키면 된다
이벤트 사용 시 주의 사항
1. 이벤트 이름은 came|Case로 작성
예를 들어 HTML의 onclick은 리액트에서는 onClick으로 작성해야 한다
2. 이벤트에 실행할 함수 형태의 값을 전달
자바스크립트 코드를 전달x 함수 형태의 값을 전달한다
화살표 함수 문법으로 전달하던가, 렌더링 부분 외부에 미리 만들어서 전달해야 한다
3. DOM 요소에만 이벤트를 설정
div, button, input 등의 DOM요소에는 이벤트 설정을 할 수 있지만,
직접 만든 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다
예를 들어 MyComponent에 onClick 이벤트를 설정한다면 MyComponent를 클릭할 때 doSomething함수를 실행하지 않는다
그냥 이름이 onClick인 props를 전달받는다
<MyComponent onClick={doSomething} />
따라서 자체적으로 이벤트를 설정할 수는 없다
전달받은 props를 컴포넌트 내부 DOM이벤트로 설정은 가능하다
<div onClick={this.props.onClick}>{}</div>
이벤트 종류
Touch, Form, UI, Media 등등..
리액트 매뉴얼 참고 https://reactjs.org/docs/events.html
이벤트 핸들링 예제
1. 컴포넌트 생성
src디렉토리에 EventPractice.js 파일 생성
import React, { Component } from 'react';
class EventPractice extends Component {
render() {
return (
<div>
<h1>이벤트 연습</h1>
</div>
);
}
}
export default EventPractice;
2. App.js에서 EventPractice 불러오기
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import EventPractice from './EventPractice';
class MyComponent extends Component {
render() {
return (
<EventPractice/>
);
}
}
export default MyComponent;
3. onChange 이벤트 핸들링
이제 input요소를 렌더링해서 onChange이벤트를 설정할 것
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.target.value);
}
}
/>
</div>
);
}
}
export default EventPractice;
EventPractice.js에 이렇게 수정해준다
여기서 넘어가는 e객체는 SyntheticEvent로 웹 브라우저의 네이티브 이벤트를 감싸는 객체이다
값이 바뀔 때마다 바뀌는 값이 콘솔에 기록된다
4. state에 input값 담기
전에 해봤던 생성자 메서드 constructor에서 state초깃값 설정, setState로 업데이트한다
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
})
}
}
/>
</div>
);
}
}
export default EventPractice;
이제 입력박스에 메시지를 잘 입력하는 것을 볼 수 있다
5. 버튼을 누를 때 comment 값을 공백으로 바꾸기
버튼을 누르면 메시지를 화면에 표시하고 comment값을 초기화한다
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
})
}
}
/>
<button onClick={
()=>{
alert(this.state.message);
this.setState({
message: ''
});
}
}>확인</button>
</div>
);
}
}
export default EventPractice;
6. 임의 메서드 만들기
아까 주의 사항에서 '이벤트에 실행할 자바 스크립트가 아니라 함수 형태의 값을 전달한다'라고 했는데,
그렇기 때문에 이벤트를 처리할 때 렌더링을 하는 동시에 함수를 만들어서 전달했다
그리고 이런 방법 대신 함수를 미리 준비해서 전달하는 방법도 있음
아래는 기본 방식
import React, { Component } from 'react';
class EventPractice extends Component {
state={
message: ''
}
constructor(props){
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleChange(e){
this.setState({
message: e.target.value
});
}
handleClick(e){
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에 접근할 수 없기 때문에
컴포넌트의 생성자 메서드인 constructor에서 각 메서드르르 this와 바인딩 해 주었다
바인드bind는 묶는다는 뜻이니까, 메서드에서 this를 사용할 수 있도록 메서드에 this를 묶어준다는 의미다
이 작업을 해주지 않으면 메서드에서 this를 부를 때 undefined가 리턴된다
7. Property Initializer Syntax를 사용한 메서드 작성
메서드 바인딩은 생성자 메서드에서 하는 것이 정석인데, 새 메서드를 만들 때마다 constructor을 수정해줘야 해서 불편하다
이 작업을 간단하게 해 주는 방법이 바로 바벨의 transform-class-properties문법으로 화살표 함수 형태로 정의하는 것
import React, { Component } from 'react';
class EventPractice extends Component {
state={
message: ''
}
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}
onChange={this.handleChange}
/>
<button onClick={this.handleClick}>확인</button>
</div>
);
}
}
export default EventPractice;
constructor가 사라지고 화살표 함수 형태가 되었다
8. input 여러 개를 핸들링
event객체를 활용하면 여러 개의 input 처리가 가능하다
import React, { Component } from 'react';
class EventPractice extends Component {
state={
username: '',
message: ''
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
});
}
handleClick = (e) => {
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}
onChange={this.handleChange}
/>
<input
type="text"
name="message"
placeholder="아무거나 입력하세요"
value={this.state.message}
onChange={this.handleChange}
/>
<button onClick={this.handleClick}>확인</button>
</div>
);
}
}
export default EventPractice;
[e.target.name]: e.target.value 이 부분에서 []는
[]안에 있는 값을 key값으로 사용한다는 의미로 쓰인다
괄호가 없으면 에러가 나니 주의한다
9. onKeyPress 이벤트 핸들링
키를 눌렀을 때 발생하는 KeyPress이벤트를 처리한다
comment인풋에서 엔터를 눌렀을 때 handleClick메서드를 호출한다
import React, { Component } from 'react';
class EventPractice extends Component {
state={
username: '',
message: ''
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
});
}
handleClick = (e) => {
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
type="text"
name="message"
placeholder="아무거나 입력하세요"
value={this.state.message}
onChange={this.handleChange}
onKeyPress={this.handleKeyPress}
/>
<button onClick={this.handleClick}>확인</button>
</div>
);
}
}
export default EventPractice;
이제 값을 입력하고 엔터를 누르면 바로 메시지창이 뜬다
참고한 책: 리액트를 다루는 기술
'Web > React' 카테고리의 다른 글
React-컴포넌트 반복(map()과 key) (0) | 2020.07.07 |
---|---|
React-ref (DOM에 이름 달기) (0) | 2020.07.07 |
React-컴포넌트(컴포넌트 생성, props, state) (0) | 2020.07.06 |
Typo in static class property declaration react/no-typos 에러 해결 방법 (0) | 2020.07.06 |
React-App.js 코드 살펴보기, JSX (0) | 2020.07.06 |