이벤트(event): 사용자가 웹 브라우저에서 DOM 요소들과 상호작용하는 것으로 클릭, 키보드 입력 등의 사용자의 행위
이벤트 핸들링: 이벤트(event)를 처리하는 것
자바스크립트의 이벤트 실행
<!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>
// Say.js
import React, { useState } from 'react';
const Say = () => {
const [message, setMessage] = useState('');
const onClickEnter = () => setMessage('안녕하세요!');
const onClickLeave = () => setMessage('안녕히 가세요!');
const [color, setColor] = useState('black');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1 style={{ color }}>{message}</h1>
<button style={{ color: 'red' }} onClick={() => setColor('red')}>
빨간색
</button>
<button style={{ color: 'green' }} onClick={() => setColor('green')}>
초록색
</button>
<button style={{ color: 'blue' }} onClick={() => setColor('blue')}>
파란색
</button>
</div>
);
};
export default Say;
위 코드는 3장에서 다루었던 버튼 코드(Say.js)이다.
컴포넌트에 자체적으로 이벤트를 설정할 수 없다.
// App.js
<MyComponent onClick={doSomething}/>
// onClick인 props를 Myconponent에 전달
전달받은 props를 컴포넌트 내부의 DOM 이벤트로 설정할 수 있다.
// 컴포넌트.js
<div onClick={this.props.onClick}>
{ /* (…) */ }
</div>
리액트에서 지원하는 이벤트 종류
나머지 이벤트는 리액트 매뉴얼(https://facebook.github.io/react/docs/event.html)을 참고
① EventPractice 컴포넌트 생성
// EventPractice.js
import React, { Component } from 'react';
class EventPractice extends Component {
render() {
return (
<div>
<h1>이벤트 연습</h1>
</div>
);
}
}
export default EventPractice;
② App.js에서 EventPractice 렌더링
// App.js
import React from 'react';
import EventPractice from './EventPractice';
const App = () => {
return <EventPractice />;
};
export default App;
① onChange 이벤트 설정
<input> 태그를 추가, 태그 내에 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);
}
}
/>
</div>
);
}
}
export default EventPractice;
e 객체: SyntheticEvent(합성 이벤트), 웹 브라우저의 네이티브 이벤트(고유 이벤트)를 감싸는 객체
# SyntheticEvent: 이벤트 핸들링을 할 때, 모든 브라우저에서 이벤트를 동일하게 처리하기 위해 받는 객체
# 네이티브 이벤트: 브라우저의 고유 이벤트
*출처: React 문서 - 합성 이벤트: https://ko.reactjs.org/docs/events.html
② onChange 코드 수정
e.target.value: 이벤트가 발생할 때마다 이벤트가 발생하는 target의 value
console.log(e.target.value): 이벤트가 발생할 때마다 e.target.value를 콘솔 출력
onChange={
(e) => {
console.log(e.target.value);
}
}
③ state에 input 담기
state 객체를 선언 및 정의: state 초깃값 설정
input의 value값에서 state 사용
onChange 이벤트가 발생할 때 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;
위의 사진과 같은 결과가 나온다.
④ 버튼을 누를 때 comment 값을 공백으로 설정
input 요소에 button을 생성
button에 onClick 이벤트가 발생, alert를 통해 현재 message값을 출력 후 setState()를 통해 message 값 공백으로 설정
import React, { Component } from ‘react‘;
class EventPractice extends Component {
state = {
message: ''
}
render() {
return (
<div>
<h1>이벤트 연습</h1>
<input
(…)
/>
<button onClick={
() => {
alert(this.state.message);
this.setState({
message: ''
});
}
}>확인</button>
</div>
);
}
}
export default EventPractice;
이벤트를 설정할 때 함수 형태의 값을 전달한다.
① 기본 방식
위의 코드를 메서드를 만들어서 다시 작성하였다.
bind(this): 메서드와 this 관계가 끊어지지 않도록 함. 임의 메서드에서 이벤트가 발생해도 this가 컴포넌트를 가리키게 하는 작업
# 바인딩: 프로그램에 사용된 요소에 속성을 연결하는 과정
// EventPractice.js
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() {
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;
② Property Initializer Syntax를 사용한 메서드 작성
메서드를 만들 때마다 생성자 메서드(constructor)를 수정해야 하는 불편함
→ 화살표 함수 형태로 메서드 작성
// EventPractice.js
import React, { Component } from 'react';
class EventPractice extends Component {
state = {
message: ''
}
//constructor 삭제
handleChange = (e) => { // 화살표 함수로 수정
this.setState({
message: e.target.value
});
}
handleClick = () => { // 화살표 함수로 수정
alert(this.state.message);
this.setState({
message: ''
});
}
//...
export default EventPractice;
event.target.name: 이벤트가 발생했을 때의 target의 이름
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: ''
});
}
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;
핵심: EventPractice의 handleChange 함수
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
객체 내의 key 값을 [ ](대괄호)로 둘러싸면 안에 넣은 레퍼런스가 가리키는 실제 값이 key로 사용
const name = ‘variantKey‘;
const object = {
[name]: ‘value‘
};
{
‘variantKey‘: ‘value‘
}
onKeyPress: 키를 눌렀을 때 발생하는 이벤트
handKeyPress 메서드 추가, input에서 onKeyPress에 대한 이벤트 설정
import React, { Component } from 'react';
class EventPractice extends Component {
//...
handleKeyPress = (e) => {
if(e.key === 'Enter') {
this.handleClick();
}
}
render() {
return (
<div>
//...
<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;
이 코드에서는 e.target.name을 사용하지 않고 onChange 관련 메서드를 따로 생성
input 개수가 많아질수록 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;
▶ 수정 코드 - e.target.name 활용하기
userState 상태값에 문자열이 아닌 객체를 넣는다.
import React, { useState } from 'react';
const EventPractice = () => {
const [form, setForm] = useState({ // 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
type="text"
name="message"
placeholder="아무거나 입력해 보세요"
value={message}
onChange={onChange} /*/
onKeyPress={onKeyPress}
/>
<button onClick={onClick}>확인</button>
</div>
);
};
export default EventPractice;
1. 사용자가 웹 브라우저에서 DOM 요소와 상호작용하는 것을 ( 이벤트 )(이)라고 하며, 이를 처리하는 것을 ( 이벤트 핸들링 )(이)라고 한다.
2. 리액트에서 이벤트를 사용할 때 주의사항이다. 이벤트의 이름은 ( 카멜표기법 )을/를 따라야 하며, 이벤트를 설정할 때 ( 함수 ) 형태의 표기법을 따른다.
3. ( bind ) 함수는 호출하는 메서드와 this가 가리키는 값이 끊어지지 않도록 하는 메서드로, 이벤트가 발생해도 컴포넌트를 가리키도록 설정한다.
4. ( e.target.name )은/는 이벤트가 발생했을 때 이벤트가 발생한 타겟의 이름을 의미하는 코드로, 이벤트를 처리할 때 자주 사용하는 코드이다.
5. 객체 내의 key 값을 ( [ ](대괄호) )(으)로 둘러싸면 안에 넣은 레퍼런스가 가리키는 실제 값이 key로 사용된다.
6. 키를 입력했을 때 발생하는 이벤트를 ( onKeyPress )(이)라고 한다.
7. 함수형 컴포넌트에서 event.target.name을 사용할 때 useState의 상태값에 문자열이 아닌 ( 객체 )을/를 넣는다.
1. onChange 이벤트 핸들링하기: input의 값이 바뀔때마다 콘솔창에 input의 value값이 출력되도록 코드 작성
// 4_pratice_1.js
import React, { Component } from 'react';
class EventPractice extends Component {
render() {
return (
<div>
<h1>이벤트 연습</h1>
<input
type='text'
name='message'
placeholder='아무거나 입력해 보세요'
onChange={
//...
}
/>
</div>
);
}
}
export default EventPractice;
2. 코드 작성하기
(1) Property Initializer Syntax를 사용한 메서드 작성 : 생성자 메서드를 삭제하고 각 메서드들을 화살표 함수로 바꾸기
(2) 2번째 input에서 Enter을 누르면 onKeyPress 이벤트 발생: onKeyPress 메서드(handleKeyPress)를 구현, 메서드 내에 Enter을 입력했을 때 handleClick() 메서드를 실행하도록 코드를 작성한다.
// 4_pratice_2.js
import React, { Component } from 'react';
class EventPractice extends Component {
state = {
username: '',
message: ''
}
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleChange(e){
this.setState({
[e.target.name]: e.target.value
});
}
handleClick(){
alert(this.state.username + ': ' + this.state.message);
this.setState({
username: '',
message: ''
});
}
//handleKeyPress 함수 구현
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} //onKeyPress 발생 시 handleKeyPress 메서드 호출
/>
<button onClick={this.handleClick}>확인</button>
</div>
);
}
}
export default EventPractice;
Corner React Starter #2
Editor 유숨숨
<리액트를 다루는 기술> 6장: 컴포넌트 반복 (0) | 2021.11.29 |
---|---|
<리액트를 다루는 기술> 5장: ref: DOM에 이름 달기 (0) | 2021.11.22 |
<리액트를 다루는 기술> 3장: 컴포넌트 (0) | 2021.11.08 |
<리액트를 다루는 기술> 2장: JSX (0) | 2021.11.01 |
<리액트를 다루는 기술> 1장: 리액트 시작 (0) | 2021.11.01 |