지난시간에는 Class 형 컴포넌트에서 state 가 업데이트 될때 자동으로 호출되는 componentDidUpdate 를 알아보았다 그렇다면 함수형 컴포넌트에서는 어떻게 이를 만들 수 있을까? 사실 이는 우리가 앞에서 한번 보았다 그래도 다시 함수형 컴포넌트로 만들어서 진행을 해보자
useEffect
useEffect(() => {호출할 함수}, 의존성 변수)
useEffect 를 사용하는 방법은 이와 같이 사용을 합니다 다만 우리는 앞에서 useEffect 를 사용을 했다
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
const get_commentList = async() => {
try{
const response = await fetch('http://localhost:8080/v1/api/getCommentList' , {
method : "GET" ,
headers : {},
}).then(res => {
const status = res.status;
if(status !== 200){
alert('서버와의 통신이 실패했습니다')
}else{
return res.json();
}
}).then(res2 => {
setCommentList(res2);
})
}catch(error){
console.log(error)
}
}
useEffect(() => {
get_commentList();
}, [])
지금 보면 함수 하나와 useEffect() 가 보이고 있다 이때 의존성 변수 [] 에 주목을 해보자 이 의존성 변수가 [] 이렇게 빈 배열로 있는 경우는 componentDidMount 와 같은 역활을 하게 된다 즉 컴포넌트가 완전히 렌더링되고 나서 딱 한번 호출되는 callback 함수이고 만약 이 의존성 변수에 특정한 값을 넣어서 변동을 만들게 되면 그 useEffect 는 componentDidUpdated 와 같은 역활을 하게 됩니다
실전 사용
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import React, { useEffect, useState } from "react";
function Function_mount2(props){
const [commentList , setCommentList] = useState([]);
const [commentCount , setCommentCount] = useState(0);
const getCommentList = async() => {
try{
const response = await fetch("http://localhost:8080/v1/api/getCommentList" , {
method : "GET",
async : true ,
headers : {},
}).then( (res) => {
const status = res.status;
if(status === 200){
return res.json();
}else{
alert('서버와의 통신이 실패했습니다')
}
}).then( (res2) => {
setCommentList(res2);
setCommentCount(res2.length);
})
}catch(error){
console.log(error)
}
}
const add_commentList = async() => {
try{
const param_commentList = commentList.filter(x => x.newComment === 'Y');
if(param_commentList.length > 0){
const response = await fetch("http://localhost:8080/v1/api/addCommentList" , {
method : "POST" ,
async : true ,
headers : {
"Content-Type": "application/json",
},
body : JSON.stringify(param_commentList)
}).then( res => {
const status = res.status;
if(status === 200){
return res.json();
}else{
alert('서버와의 통신이 실패했습니다')
}
}).then( (res2) => {
getCommentList();
})
}
}catch(error){
console.log(error)
}
}
const add_comment = () => {
const add_name = document.querySelector("#input_name").value;
const add_comment = document.querySelector("#input_comment").value;
const new_comment_object = {
name : add_name ,
comment : add_comment,
newComment : "Y"
}
const new_commentList = [...commentList , new_comment_object]
setCommentList(new_commentList)
setCommentCount((preCommentCount) => preCommentCount + 1);
}
/*commponentDidMount*/
useEffect(() => {
getCommentList();
} , [])
/*commponentDidUpdate*/
useEffect(() => {
add_commentList();
} , [commentCount])
return (
<div>
{commentList.map(x=> {
return (
<div>
name : <span>{x.name}</span>
comment : <span>{x.comment}</span>
</div>
)
})}
<div>
name : <input id = "input_name" type="text"/>
comment : <input id = "input_comment" type="text"/>
<button onClick={add_comment}>댓글 달기</button>
</div>
</div>
)
}
export default Function_mount2;
좀 길어보이지만 천천히가보자 지난시간하고 동일한 api 이고 동일한 fetch 이기 때문에 그에 대한 설명은 넘어가고 useState 와 useEffect 에만 집중을 하겠습니다
useState
1
2
3
4
const [commentList , setCommentList] = useState([]);
const [commentCount , setCommentCount] = useState(0);
useState 는 2개의 변수를 선언했습니다 하나는 앞에서 댓글을 진짜 받아줄 수 있는 메인 배열을 하나 만들었고 뒤에 있는 commentCount 는 CommentList 의 댓글의 길이를 가질 state 를 선언했습니다
useEffect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*commponentDidMount*/
useEffect(() => {
getCommentList();
setCommentCount(commentList.length);
} , [])
/*commponentDidUpdate*/
useEffect(() => {
add_commentList();
} , [commentCount])
첫번째 useEffect 설명 (commponentDidMount)
지금보면 useEffect 가 2개 있습니다 리액트의 라이프사이클을 이해를 하게 되면 이렇게 useEffect 를 적재적소에 배치할 수 있게 됩니다 그리고 그에 대한 컨트롤은 의존성 배열로 호출시점을 지정할 수 있습니다 지금 보면 2개의 useEffect 에 제가 각각 주석을 달아두었습니다
첫번째 useEffect 는 [] 있는 의존성 배열로 이는 componentDidMount 역활을 하게 됩니다 즉 컴포넌트가 완전히 렌더링된 이후 호출되는 useEffect 이고 이때 호출은 서버api 를 호출하게 되며 이 api 호출로 저장되어 있는 comment 를 가져오게 됩니다 이때 fetch 를 잘 살펴보게 되면
1
2
3
4
5
6
.then( (res2) => {
setCommentList(res2);
setCommentCount(res2.length);
})
이렇게 2개의 set함수가 있는것을 알 수 있습니다 하나는 commentList 의 데이터를 넣는 set과 그리고 다른 하나는 commentList 의 length 를 값을 대입하는 set 함수입니다
두번째 useEffect 설명 (commponentDidUpdate)
그럼 이제 2번째로 가보자 두번쨰는 의존성 배열에 commentCount 것을 볼 수 있습니다 이것으로 우리는 add_commentList() 함수의 호출을 조절 할 수 있습니다 commentCount 의 값이 변경이 되면 자동으로 리액트가 useEffect 활용해서 add_commentList 를 호출하게 되고 이때 state 가 변하게 되었으므로 이 useEffect 는 class 컴포넌트에서 componentDidUpdate 와 같은 역활을 하게 되는 것입니다
어디서 commentCount 를 올려주는가?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const add_comment = () => {
const add_name = document.querySelector("#input_name").value;
const add_comment = document.querySelector("#input_comment").value;
const new_comment_object = {
name : add_name ,
comment : add_comment,
newComment : "Y"
}
const new_commentList = [...commentList , new_comment_object]
setCommentList(new_commentList)
setCommentCount((preCommentCount) => preCommentCount + 1);
}
버튼의 이벤트이다 버튼은 지난시간과 동일한 버튼에 딱 하나 setCommentList(new_commentList)
setCommentCount((preCommentCount) => preCommentCount + 1)
를 만들었습니다 이를 통해서 우리는 commentCount 를 변하였고 state 의 변화를 감지한 두번째 useEffect 가 동작을 하면서 서버에 데이터를 저장하는 api 를 호출하게 됩니다
우리는 이렇게 지난시간에 한 class 형 컴포넌트와 , 함수형 컴포넌트에서 componentDidUpdate 에 대해서 공부를 해보았습니다 다음 시간에는 마지막 컴포넌트 unmount 에 대해서 알아볼 예정입니다