4-1. 리액트의 이벤트 시스템
1) 이벤트를 사용할 때 주의 사항
- 이벤트 이름은 카멜 표기법으로 작성한다.
- ex) onclick(x) -> onClick
- 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달한다.
- DOM 요소에만 이벤트를 설정할 수 있다.
- 직접 만든 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다.
4-2. 예제로 이벤트 핸들링 익히기
1) onChange 이벤트
- onChange 이벤트는 Form 요소에 값이 변하면 발생하는 이벤트이다.
- onChange 함수안에 e 객체는 SyntheticEvent, 웹 브라우저의 네이티브 이벤트를 감싸는 객체이다.
- 이벤트가 끝나고 나면 초기화되므로 정보를 참조할 수 없다.
- 만약 비동기적으로 이벤트 객체에 참조할 일이 생긴다면 밑에 코드를 보면 알 수 있다.
- onChange 함수 안에 setTimeout 함수를 적용 시키려면 e.persist() 함수를 호출해주면 정상적으로 작동이 된다.
- e.persist() 함수를 넣어주는 이유는 기존에 사용하고 있던 이벤트 풀 ( Event Pool ) 에서 제거되고 사용자 코드로
사용이 되기 때문!!
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) => {
e.persist();
console.log(e.type);
console.log(e.target.value);
setTimeout(() => {
console.warn(e.type);
});
}
/>
</div>
);
}
}
export default EventPractice;
2) 임의 메서드 만들기
- 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달한다.
- 성능상으로는 차이가 거의 없지만, 가독성은 훨씬 높다.
- 밑에 코드를 보면 constructor안에 bind(this)가 되있는데 임의 메서드가 이벤트로 등록되어도 this가 컴포넌트
자신으로 제대로 가르키기 위해서는 메서드를 this와 바인딩하는 작업이 필요하다.
- 바인딩하지 않는 경우라면 this가 undefined를 가리키게 된다.
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;
3) Property Intializer Syntax 를 사용한 메서드 작성
- 메서드 바인딩은 생성자 메서드에서 하는 것이 정석이다. 그렇다보니 새 매서드를 만들 때마다 constructor도
수정해야 하는게 불편할 수 있다.
- 이것을 간단하게 하는 방법도 있는데 바벨의 transform-class-properties 문법을 사용하여 화살표 함수형태로
메서드를 정의 할 수 있다.
- 화살표 함수를 통해서 thisReact 구성 요소 내에서 정의한 모든 메서드에 컨텍스트를 종속적으로 바인딩할 필요가
없어진다.
- 코드가 훨씬 간결하고 깔끔해진다.
<생성자 메서드를 사용한 형태>
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: ''
});
}
<화살표 함수 형태>
handleChange = (e) => {
this.setState({
message: e.target.value
});
}
handleClick = () => {
alert(this.state.message);
this.setState({
message: ''
});
}
4) input 여러 개 다루기
- input이 여러 개일 때 메서드를 여러 개 만드는 것도 방법이지만 더 쉽게 처리하기 위해서는 event 객체를
활용하는 것이다.
- e.target.name 값을 활용하면 된다.
- e.target.name에 각각 input에서 설정한 name 값이 들어가게 되고
- e.target.value는 각각 input에서 입력한 input value값이 들어가게 된다
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;
- [e.target.name] 을 작성한 이유는 객체 안에서 key를 []로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이
key로 사용된다.
//위에 내용을 추가로 덧붙이자면 다음과 같은 객체가 있을때
const name = "홍길동";
const object = {
[name] : 'value'
}
// 결과는 다음과 같다.
{
'홍길동' : 'value'
}
4-3. 함수 컴포넌트로 구현해 보기
- 아래의 코드에서 const { username, message } = form; 이것을 넣은 이유는 form.username , form.message를
넣을 수 있지만 편하게 사용하기 위해서 비구조화 할당을 해준 것이다.
import React, { useState } from 'react';
const EventPractice = () => {
const [form, setForm] = useState({
username: '',
message: ''
});
const { username, message } = form;
//바로 위의 코드의 의미는 다음과 같다.
// const form: {
// username: string;
// message: string;
// }
//불변성 유지를 위해
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;
'Frontend > ReactJS(완)' 카테고리의 다른 글
React - 6장 : 컴포넌트 반복 (0) | 2023.02.13 |
---|---|
React - 5장 : ref. DOM에 이름 달기 (0) | 2023.02.09 |
React - 3장 : 컴포넌트 (0) | 2023.02.06 |
React - 2장 : JSX (0) | 2023.02.02 |
React - 1장 : React 이해 (0) | 2023.02.01 |
댓글