우리는 지난시간까지 React 의 라이프 사이클에 대해서 공부를 해보았습니다 이번시간에는 Event 에 대해서 공부를 해보겠습니다
Event
웹어플리케이션에서 Evnet 라는것은 어떤 사건을 말합니다 이때 이 Event 는 정말 다양한데 어떤 버튼을 눌렀다 form 양식에 데이터를 입력했다 등 정말 수 많은 이벤트로 웹사이트가 이루어져 있습니다 우리는 간단한 웹사이트를 만들기 전에 이 Event 에 대해서 알아보도록 하겠습니다 마찬가지로 class 컴포넌트 버전과 함수 컴포넌트형 버전으로 정리를 하겠습니다
바닐라 자바스크립트에서 이벤트
먼저 우리가 아는 통상적인 자바 스크립트 이벤트에 대해서 알아보겠습니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<head>
</head>
<body>
<button onclick="btn_click()">클릭 버튼</button>
<script type="text/javascript">
function btn_click(){
alert(123)
}
</script>
</body>
</html>
기억을 더듬어서 바닐라 자바스크립트의 클릭이벤트를 만들어보면 이와 같은 모양으로 만들어졌습니다 “” 안에 호출할 함수를 만들어 놓는 것입니다 이렇게 하면 자바 스크립트에서 간단한 버튼 클릭 이벤트가 만들어진것입니다
React 클래스형 컴포넌트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import React from "react";
class Class_btn_event extends React.Component{
constructor(props){
super(props)
this.state = {
count : 0
}
}
call_alert(){
alert('버튼클릭했습니다')
this.setState((precount) => ({count : precount.count + 1}))
}
render(){
return (
<div>
<button onClick={this.call_alert}>클릭</button>
</div>
)
}
}
export default Class_btn_event;
이번에는 React 컴포넌트중에 Class 형 으로 버튼클릭 이벤트를 만들어보고 이때 이 이벤트를 활성화 하는 방법에 대해서 알아보겠습니다
마찬가지로 onClick 에 JSX 구조로 this.call_alert 함수를 호출하게끔 만들었고 이때 함수는 call_alert 를 호출하면서 alert 을 띄우게 됩니다 그리고 state 의 값을 변경할 것이라고 예상을 합니다 다만 클릭을 해보면 오류가 발생합니다
클래스형 컴포넌트의 이벤트 주의점
위 코드에서 오류가 나는 이유는 this 가 문제점입니다 class 형 컴포넌트의 가장 큰 문제점은 this 는 window 를 가리키기 때문에 this.state 를 찾아 올 수 없는 오류가 생깁니다 이때 해결할 수 있는 방식 2가지가 존재합니다
bind 사용
1
2
3
4
5
6
7
8
9
constructor(props){
super(props)
this.state = {
count : 0
}
this.call_alert = this.call_alert.bind(this)
}
constructor 에 bind 를 사용해서 this 를 명시를 해주시면됩니다
Array function 사용
1
2
3
4
5
6
7
call_alert = () => {
alert('버튼클릭했습니다')
this.setState((precount) => ({count : precount.count + 1}))
}
bind 없이 사용할때는 함수 자체를 Array 형으로 사용하면 bind 없이도 state 에 접근할 수 있습니다
OnChange
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import React from "react";
class Class_btn_event extends React.Component{
constructor(props){
super(props)
this.state = {
name : "" ,
count : 0
}
this.call_alert =this.call_alert.bind(this)
}
call_alert(){
const name = this.state.name;
const count = this.state.count
alert(`당신의 이름은 ${name} 이고 버튼클릭은 ${count} 번째 입니다`)
this.setState((preCount) => ({count : preCount.count + 1}))
}
change_name(event){
this.setState({name : event.target.value})
}
render(){
return (
<div>
<span>
이름 : <input type="text" onChange={(event) => this.change_name(event)} value={this.state.name}></input>
</span>
<button onClick={this.call_alert}>이름표 출력</button>
</div>
)
}
}
export default Class_btn_event;
앞의 예제에서 input 을 포함을 시켰고 이때 onChage 이벤트를 걸었습니다 이때 생겨나는 궁금증 왜 change_name bind 를 걸어주지 않았으냐? 이때는 현재 onChange 자체가 함수형으로 구현이 되어 있기 때문에 bind 를 사용하지 말아야 합니다 이때 bind 를 명시적으로 구현을 하게 되면 에러가 발생하게 됩니다
event 매개변수
React 모든 컴포넌트는 공통적인 매개변수를 가지는데 그중 하나가 바로 event 입니다 이 event 매개변수는 이벤트 객체입니다 이벤트 객체에는 이벤트가 발생한 요소 마우스 포인터 위치 키보드 입력등과 같은 값을 가지고 있습니다 그래서 여기서 입력한 event 값을 전달받아서 사용할 수 있습니다 우리는 그것을 바로 state 에 적용을 시켰습니다
암시적 event 변수 사용
지금처럼 (event) => this.change_name(event)
사용해서 명시적으로 event 객체가 있는것을 보여주지만 실제로 호출할때 넣어주지 않아도 사용할 수 있습니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
change_name = (event) => {
this.setState({name : event.target.value})
}
render(){
return (
<div>
<span>
이름 : <input type="text" onChange={this.change_name} value={this.state.name}></input>
</span>
<button onClick={this.call_alert}>이름표 출력</button>
</div>
)
}
암시적으로 전달할때는 이와 같은 방식으로 전달할 수 있습니다 이때 array 함수를 사용했고 만약 array 함수 사용하지 않을려면 button 처럼 bind 를 사용해서 this 를 명시해주시면됩니다
함수형 컴포넌트는 이와 같이 구현할 수 있습니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import React, { useState } from "react";
function Function_btn_event(props){
const [count , setCount] = useState(0)
const [name , setName] = useState("")
const change_name = (event) => {
setName(event.target.value)
}
const call_alert = () => {
alert(`당신의 이름은 ${name} 이고 버튼클릭은 ${count} 번째 입니다`)
setCount((precount) => precount + 1)
}
return (
<div>
함수형 이벤트
<span>
이름 : <input type="text" onChange={change_name} value={name}></input>
</span>
<button onClick={call_alert}>이름표 출력</button>
</div>
)
}
export default Function_btn_event