
이 포스팅은 김민준님의 '리액트를 다루는 기술'을 요약한 글입니다.
이벤트 : 웹브라우저에서 DOM 요소들과 상호작용 하는 것
// EventPractice.js
import { Component } from 'react';
class EventPractice extends Component{
state={
message:'' // state 초깃값 설정
}
render(){
return(
<div>
<h1>이벤트 연습</h1>
<input
type="text"
name="message"
placeholder="아무거나 입력해 보세요"
value={this.state.message} // input의 value 값을 state에 있는 값으로 설정
onChange={
(e) => {
this.setState({
message: e.target.value // state를 업데이트
})
}
}
/>
<button onClick={
() => {
= alert(this.state.message);
this.setState({
message: '' // comment 값을 공백으로 설정
});
}
}>확인</button>
</div>
)
}
}
export default EventPractice;
함수가 호출될 때 this는 호출부에 따라 결정되므로, 클래스의 임의 메서드가 특정 HTML 요소의 이벤트로 등록되는 과정에서 메서드와 this의 관계가 끊어져 버립니다. 이 때문에 임의 메서드가 이벤트로 등록되어도 this를 컴포넌트 자신으로 제대로 가리키기 위해서는 메서드를 this아 바인딩하는 작업이 필요합니다. 만약 바인딩하지 않는 경우라면 this가 undefined를 가리키게 됩니다.
아래 코드를 보면 constructor 함수에서 함수를 바인딩하는 작업이 이루어지고 있습니다.
// EventPractice.js
import { Component } from 'react';
class EventPractice extends Component{
state={
message:'' // state 초깃값 설정
}
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleChange(e) {
this.setState({
message: e.target.value // 입력된 값으로 state값을 업데이트
});
}
handleClick() {
alert(this.state.message);
this.setState({
message: '' // state값을 공백으로 초기화
});
}
render(){
return(
<div>
<h1>이벤트 연습</h1>
<input
type="text"
name="message"
placeholder="아무거나 입력해 보세요"
value={this.state.message} // input의 value 값을 state에 있는 값으로 설정
onChange={this.handleChange} // 변경사항이 있으면 handleChange 이벤트 실행
/>
<button onClick={this.handleClick}>확인</button> {/* 클릭 시 handleClick이벤트 실행 */}
</div>
)
}
}
export default EventPractice;
메서드 바인딩은 생성자 메서드에서 하는 것이 정석입니다.
새 메서드를 만들 때마다 constructor도 수정하는 것이 번거롭기 때문에 더 간단하게 하기 위해서 바벨의 transform-class-properties 문법을 사용하여 화살표 함수 형태로 메서드를 정의해 보겠습니다.
// EventPractice.js
import { Component } from 'react';
class EventPractice extends Component{
state={
message:'' // state 초깃값 설정
}
handleChange = (e) => {
this.setState({
message: e.target.value // 입력된 값으로 state값을 업데이트
});
}
handleClick = () => {
alert(this.state.message);
this.setState({
message: '' // state값을 공백으로 초기화
});
}
render(){
return(
<div>
<h1>이벤트 연습</h1>
<input
type="text"
name="message"
placeholder="아무거나 입력해 보세요"
value={this.state.message} // input의 value 값을 state에 있는 값으로 설정
onChange={this.handleChange} // 변경사항이 있으면 handleChange 이벤트 실행
/>
<button onClick={this.handleClick}>확인</button> {/* 클릭 시 handleClick이벤트 실행 */}
</div>
)
}
}
export default EventPractice;
// EventPractice.js
import { 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;
객체 안에서 key를 [ ]로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이 key 값으로 사용됩니다.
예를 들어 다음과 같은 객체를 만들면
const name = 'variantKey';
const object = {
[name] : 'value'
};
결과
{
‘variantKey’ : ‘value’
}
// EventPractice.js
import { 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: ''
});
}
**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;
// EventPractice.js
import { 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;
// EventPractice.js
// 인풋값이 많아질 경우 활용하기 좋은 예제
import { 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:'',
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;