4장 이벤트 핸들링
이벤트(Event)
- 사용자가 웹 브라우저에서 DOM 요소들과 상호 작용을 하는 것
- ex. 버튼_마우스 커서 -> onmouseover 이벤트 실행/ 클릭 -> onclick 이벤트 실행
/ Form 요소_값 변경 -> onhange 이벤트 실행
1. 리액트의 이벤트 시스템
이벤트 사용 주의사항
- 이벤트 이름 -> 카멜 표기법
- ex. onclick -> onClick/ onkeyup -> onKeyUp
- 이벤트에 실행할 자바스크립트 코드 전달X, 함수 형태의 값 전달
- HTML) 큰따옴표 안에 실행할 코드 넣음
- 리액트) 함수 형태의 객체를 전달
- 바로 만들어서 전달
- 렌더링 부분 외부에 미리 만들어서 전달
- DOM 요소에만 이벤트 설정O
- div, button, input, form, span 등 DOM의 요소에 이벤트 설정 O
But, 직접 만든 컴포넌트에 이벤트 자체 설정X - ex. MyComponent에 onClick 값 설정
-> 클릭 시 doSomething 함수 실행 X 이름이 onClick인 props -> MyComponent에 전달
=> 컴포넌트 자체적으로 이벤트 설정 X 전달 받은 props를 컴포넌트 내부의 DOM 이벤트로 설정 O
- div, button, input, form, span 등 DOM의 요소에 이벤트 설정 O
<My Component onClick={doSomething}/>
<div onClick={this.props.onClick}>
{/* (...) */}
</div>
이벤트 종류
Clipboard/ Composition/ Keyboard/ Focus/ Form/ Mouse/ Selection
/ Touch/ UI/ Wheel/ Media/ Image/ Animation/ Transition
2. 예제로 이벤트 핸들링 익히기
1) 컴포넌트 생성 및 불러오기
// EventPractice.js
import React, { Component } from "react";
class EventPractice extends Component {
render() {
return (
<div>
<h1> 이벤트 연습 </h1>
</div>
);
}
}
export default EventPractice;
// App 컴포넌트 -> EventPractice 불러와 렌더링
import EventPractice from './EventPractice';
const App = () => {
return <EvnetPractice />;
};
export default App;
2) onChange 이벤트 핸들링
① onChange 이벤트 설정
// EventPractice.js
// onChange 이벤트 핸들링
<input
type="text"
name="message"
placeholder="아무거나 입력"
onChange={
// e객체: SyntheticEvent로 웹 브라우저 네이티브 이벤트 감싸는 객체
// 네이티브 이벤트 == 인터페이스
(e) => {
// 이벤트 끝나고 나면 이벤트 초기화 -> 정보 참조 X
console.log(e);
// 비동기적으로 객체 참조 -> e.persist() 함수 호출
console.log(e.targent.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
})
}
}
/>
</div>
);
}
}
export default EventPractice;
③ 버튼 누를 때 comment 값 공백으로 설정
// EventPractice.js
<input
(...)
/>
<button onClick={
() => {
alert(this.state.messgae);
this.setState({
message: ''
});
}
}>확인</button>
3) 임의 메서드 만들기
이벤트에 실행할 자바스크립트 코드 전달 X 함수 형태의 값 전달 O
-> 이벤트를 처리할 때 렌더링 + 함수 만들어서 전달/ 함수 미리 준비하여 전달(-> 가독성 ↑)
① 기본 방식
함수 호출될 때 this는 호출부에 따라 결정
-> 클래스의 임의 메서드가 특정 HTML 요소의 이벤트로 등록되는 과정에서 메서드와 this의 관계 끊어짐
=> this 컴포넌트 자신으로 제대로 가리키기 위해 -> 메서드를 this와 바인딩(binding)하는 작업 필요
IF. 바인딩 X -> this가 undefinded 가리킴
② Property Initializer Syntax를 사용한 메서드 작성
(정석) 생성자 메서드에서 메서드 바인딩
-> 새 메서드 만들 때마다 constructor 수정 => 불편
-> 바벨의 transform-class-properties 문법 사용 -> 화살표 형태로 메서드 정의
state = {
message: ''
}
// 1. 기본 방법
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleChange(e) {
this.setState({
message: e.target.value
});
}
// 2. Property Initializer Syntax
handleChange = (e) => {
this.setState({
message: e.target.value
});
}
4) input 여러 개 다루기
inpput이 여러 개 -> event 객체 활용 => e.target.name
// EventPractice.js
import React, { Component } from 'react';
class EventPractice extends Component {
state = {
username: '',
message: ''
}
// 객체 안에서 key를 []로 감싸면
// 안에 넣은 레퍼런스가 가리키는 실제 값 -> key 값으로 사용
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
});
}
handleClick = () => {
alert(this.state.username + ': ' + this.state.messgae);
this.setState({
username: '',
messgae: ''
});
}
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;
// ex.객체
const name = 'varianKey';
const object = {
[name]: 'value'
};
// 결과
{
'varianKey': 'value'
}
5) onKeyPress 이벤트 핸들링
// EventPractice.js
import React, { Component } from 'react';
class EventPractice extends Component {
state = {
username: '',
messgae: ''
}
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
type="text"
name="message"
placeholder="아무거나 입력"
value={this.state.message}
onChange={this.handleChange}
onKeyPress={this.handleKeyPress}
/>
<button onClick={this.handleClick}>확인</button>
</div>
);
}
}
export default EventPractice;
3. 함수 컴포넌트로 구현해 보기
e.target.name 활용 X onChange 관련 함수 2 개 따로 만듦
인풋 개수 ↑ -> e.target.name 활용
// EventPractice.js
import React, { useState } from 'react';
const EventPractice = () => {
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
type="text"
name="message"
placeholder="아무거나 입력"
value={message}
onChange={onChangeMessage}
onKeyPress={onKeyPress}
/>
<button onClick={onClick}>확인</button>
</div>
);
};
export default EventPractice;
useState ~> 사용하는 상태에 문자열 X 객체
e.target.name 값 활용 -> useState 쓸 때 인풋 값들이 들어 있는 form 객체 사용
// EventPractice.js
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: '',
messgae: ''
});
};
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;
정리
리액트) 이벤트 다루기 ~= 순수 자바스크립트/ jQuery 사용한 웹 애플리케이션_이벤트 다루기
(+) 자바스크립트 익숙 -> 쉽게 활용 가능
=> 기존 HTML DOM Event -> 리액트 컴포넌트 이벤트 다루기 쉬움
함수 컴포넌트) 여러 개의 인풋 상태 관리 -> useState에서 form 객체 사용
출처
'Programming Language > React' 카테고리의 다른 글
[리액트를 다루는 기술] 6장 컴포넌트 반복 (0) | 2023.01.15 |
---|---|
[리액트를 다루는 기술] 5장 ref: DOM에 이름 달기 (0) | 2023.01.15 |
[리액트를 다루는 기술] 3장 컴포넌트 (0) | 2023.01.15 |
[리액트를 다루는 기술] 1장 리액트 시작/ 2장 JSX (0) | 2023.01.15 |