리액트의 이벤트(Event)
- 리액트에서도 여러가지 함수에서 이벤트 객체를 다룰 수 있습니다.
- Vanila 자바스크립트에서 화살표 함수의 첫번째 매개변수 e는 Event 객체를 의미합니다.
- 리액트에서도 마찬가지로 화살표 함수의 첫번째 매개변수는 Event객체이나 조금 다릅니다.
- 리액트에서는 Vanila 자바스크립트를 네이티브 이벤트 객체라고 합니다. 그리고 리액트의 이벤트 객체는 이 네이티브 이벤트 객체를 감싸는 wrapper를 사용하게 됩니다.
- 이 wrapper 객체를 SyntheticEvent 객체라고 부르며 리액트에서는 이 객체를 통해 이벤트를 핸들링하게 됩니다.
- 사용 상 네이티브 이벤트 객체와 크게 다르진 않지만, 리액트 이벤트 객체인 만큼 몇 가지 다른점이 존재하긴 합니다.
- 리엑트에서는 네이티브 이벤트 객체도 물론 사용 가능합니다.
- 그러나, 리액트에서 별도로 분류하여 다루는 몇 가지 Event 들이 있습니다.
- 이 이벤트들은 아래의 공식 사이트에서 필요할 때 참고하면 될 것 같습니다.
https://reactjs.org/docs/events.html#clipboard-events
💡 들어가기 전에!
- 리엑트의 SyntheticEvent 객체는 는 이벤트 종료 후 초기화 되므로 정보를 참조할 수 없습니다.
- 예컨데 0.5초 뒤에 화살표 함수 안의 e 변수를 비동기로 참조하면 그 안의 값들이 처음과 달라집니다.
- 만약 비동기적으로 처리하고 싶다면, e.persist() 함수를 호출해주어야 합니다.
- 컴포넌트 태그에는 이벤트를 설정할 수 없습니다. (본 포스트에서는 <ClassEvent01 /> 등)
- 그러나 어떤 함수를 변수 형태로 넘겨주어 컴포넌트 내부에서 임의의 메서드를 만들 수는 있습니다.
App.js
import "./App.css";
import "./assets/Custom.css";
import { Fragment } from "react";
// 컴포넌트 삽입
// 클래스형 컴포넌트
import ClassEvent01 from "./components/ClassEvent01";
import ClassEvent02 from "./components/ClassEvent02";
import ClassEvent03 from "./components/ClassEvent03";
import ClassEvent04 from "./components/ClassEvent04";
// 함수형 컴포넌트
import FuncEvent01 from "./components/FuncEvent01";
import FuncEvent02 from "./components/FuncEvent02";
const App = () => {
const title = "리액트 컴포넌트의 EVENT HANDLING";
return (
<>
<div className="header-div">
<h1>{title}</h1>
</div>
<ClassEvent01 name="value" /> {/* 이렇게 작성하면 props 속성명이 name인 데이터로 넘거 가게 됨 */}
<ClassEvent02 />
<ClassEvent03 />
<ClassEvent04 />
<FuncEvent01 />
<FuncEvent02 />
</>
);
};
export default App;
콘솔창에서 SyntheticEvent 확인하기
클래스 컴포넌트로 이벤트 핸들러 만들기1 (ClassEvent01.js)
import { Component } from "react";
import { Fragment } from "react";
class ClassEvent01 extends Component {
state = {
text: "",
};
render() {
const { text } = this.state;
return (
<>
<div className="class-comp">
<div className="text-box">
<h1>이벤트 연습1</h1>
<p>{text}</p>
<input
type="text"
name="message"
placeholder="아무 글자나 입력해 보세요"
onChange={(e) => {
console.dir(e);
this.setState({ text: e.target.value });
}}
/>
</div>
<button
onClick={(e) => {
alert(text);
this.setState({ text: "" });
}}
>
확인
</button>
</div>
</>
);
}
}
export default ClassEvent01;
클래스 컴포넌트로 이벤트 핸들러 만들기2 (ClassEvent02.js)
import { Component } from "react";
import { Fragment } from "react";
class ClassEvent02 extends Component {
state = {
text: "",
};
// 이곳에 메서드를 작성
handleChange = (e) => {
this.setState({
text: e.target.value,
});
};
handleClick = () => {
alert(this.state.text);
this.setState({ text: "" });
};
render() {
const { text } = this.state;
return (
<>
<div className="class-comp">
<div className="text-box">
<h1>이벤트 연습2</h1>
<p>{text}</p>
<input
type="text"
name="message"
placeholder="아무 글자나 입력해 보세요"
value={text}
onChange={this.handleChange}
/>
</div>
<button onClick={this.handleClick}>확인</button>
</div>
</>
);
}
}
export default ClassEvent02;
클래스 컴포넌트로 이벤트 핸들러 만들기3 (ClassEvent03.js)
import { Component } from "react";
import { Fragment } from "react";
class ClassEvent03 extends Component {
state = {
username: "",
text: "",
};
// 이곳에 메서드를 작성
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
};
handleClick = () => {
alert(this.state.username + " : " + this.state.text);
this.setState({
text: "",
username: "",
});
};
render() {
const { text, username } = this.state;
return (
<>
<div className="class-comp">
<div className="text-box">
<h1>이벤트 연습3</h1>
<p>{username}</p>
<p>{text}</p>
<input
type="text"
name="username"
placeholder="아무 이름이나 입력해 보세요"
value={username}
onChange={this.handleChange}
/>
<br />
<input
type="text"
name="text"
placeholder="아무 글자나 입력해 보세요"
value={text}
onChange={this.handleChange}
/>
</div>
<button onClick={this.handleClick}>확인</button>
</div>
</>
);
}
}
export default ClassEvent03;
- 자바스크립트 객체의 프로퍼티 명(key 값)을 []로 감싸면 실제로 프로퍼티가 가지고 있는 값으로 바뀐다.
- e.target.name =”hello”면 name : hello이런 식으로 바뀐다는 뜻 이다.
클래스 컴포넌트로 이벤트 핸들러 만들기4 (ClassEvent04.js)
- 엔터 치면 정보가 뜨게 설정
import { Component } from "react";
import { Fragment } from "react";
class ClassEvent04 extends Component {
state = {
username: "",
text: "",
};
// 이곳에 메서드를 작성
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value,
});
};
handleClick = () => {
alert(this.state.username + " : " + this.state.text);
this.setState({
text: "",
username: "",
});
};
handleKeyPress = (e) => {
if (e.key === "Enter") {
this.handleClick();
}
};
render() {
const { text, username } = this.state;
return (
<>
<div className="class-comp">
<div className="text-box">
<h1>이벤트 연습4</h1>
<p>{username}</p>
<p>{text}</p>
<input
type="text"
name="username"
placeholder="아무 이름이나 입력해 보세요"
value={username}
onChange={this.handleChange}
onKeyDown={this.handleKeyPress}
/>
<br />
<input
type="text"
name="text"
placeholder="아무 글자나 입력해 보세요"
value={text}
onChange={this.handleChange}
onKeyDown={this.handleKeyPress}
/>
</div>
<button onClick={this.handleClick}>확인</button>
</div>
</>
);
}
}
export default ClassEvent04;
함수형 컴포넌트 이벤트 핸들러 만들기 1 (FuncEvent01.js)
import { useState, Fragment } from "react";
const FuncEvent01 = () => {
const [username, setUsername] = useState("");
const [text, setText] = useState("");
// 함수형 컴포넌트의 이벤트 핸들링 메서드
// 일단 가장 쉬운 방법은 이벤트에 맞게 메서드를 별도로 선언하는 것이다.
// 하지만 이런 식의 코드 스타일은 프로젝트가 커지면 하드코딩으로 변하기 딱 좋다...
const onChangeUsername = (e) => setUsername(e.target.value);
const onChangeText = (e) => setText(e.target.value);
const onClick = () => {
alert(username + " : " + text);
setUsername("");
setText("");
};
const handleKeyDown = (e) => {
if (e.key === "Enter") {
onClick();
}
};
return (
<>
<div className="class-comp">
<div className="text-box">
<h1>함수형 이벤트 연습1</h1>
<p>{username}</p>
<p>{text}</p>
<input
type="text"
name="username"
placeholder="아무 이름이나 입력해 보세요"
value={username}
onChange={onChangeUsername}
onKeyDown={handleKeyDown}
/>
<input
type="text"
name="text"
placeholder="아무 글자나 입력해 보세요"
value={text}
onChange={onChangeText}
onKeyDown={handleKeyDown}
/>
</div>
<button onClick={onClick}>확인</button>
</div>
</>
);
};
export default FuncEvent01;
- 함수형은 클래스형과 달리 확실히 state, 변수, 메서드 선언이 조금 까다롭다.
- 함수형 컴포넌트에서는 위와 같이 dom 별로 이벤트 핸들러를 작성할 수도 있고,
- 이것은 곧 프로젝트의 규모가 커지면 하드 코딩하게 되는 원인이 된다.
함수형 컴포넌트 이벤트 핸들러 만들기 2 (FuncEvent02.js)
import { useState, Fragment } from "react";
const FuncEvent02 = () => {
const [form, setForm] = useState({
text: "",
username: "",
});
const { text, username } = form;
const handleChange = (e) => {
const nextForm = {
...form, // 기존의 form 내용을 복사하고
[e.target.name]: e.target.value, // 원하는 값 덮어쓰기
};
setForm(nextForm);
};
const onClick = () => {
alert(username + " : " + text);
this.setForm({
text: "",
username: "",
});
};
const handleKeyDown = (e) => {
if (e.key === "Enter") {
onClick();
}
};
return (
<>
<div className="class-comp">
<div className="text-box">
<h1>함수형 이벤트 연습2</h1>
<p>{username}</p>
<p>{text}</p>
<input
type="text"
name="username"
placeholder="아무 이름이나 입력해 보세요"
value={username}
onChange={handleChange}
onKeyDown={handleKeyDown}
/>
<input
type="text"
name="text"
placeholder="아무 글자나 입력해 보세요"
value={text}
onChange={handleChange}
onKeyDown={handleKeyDown}
/>
</div>
<button onClick={onClick}>확인</button>
</div>
</>
);
};
export default FuncEvent02;
- 함수형 컴포넌트에서도 destructuring assignment 를 사용하면 소프트 코딩이 가능하다.
'프론트엔드(Front-End) > React' 카테고리의 다른 글
[REACT] 컴포넌트 요소의 반복(map, filter) (0) | 2023.01.06 |
---|---|
[REACT] 리액트의 ref (0) | 2023.01.05 |
[REACT] 리액트의 STATE (0) | 2023.01.03 |
[REACT] 리액트의 컴포넌트(COMPONENT) (0) | 2023.01.02 |
[REACT] React와 JSX (0) | 2022.12.27 |