일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- kubernetes
- 클라우드
- BFS
- 솔리디티
- 블록체인
- 백준
- AWS
- CSS
- node.js
- 백엔드
- next.js
- JavaScript
- HTML
- 가상화
- 이더리움
- 이슈
- 알고리즘
- 리액트
- 타입스크립트
- 웹
- k8s
- 프론트엔드
- 컴퓨터공학
- 쿠버네티스
- 자바스크립트
- react
- 파이썬
- es6
- TypeScript
- docker
- Today
- Total
즐겁게, 코드
useEffect 훅에 대하여 본문
useEffect
훅은 컴포넌트의 부수동작(effect) 을 담당하는 훅으로 기본 훅 중에서도 가장 중요한 훅이라 할 수 있다.
(부수동작이란 컴포넌트가 처음 마운트될때 / 컴포넌트가 업데이트될때 / 컴포넌트가 언마운트될때 일어나는 모든 동작을 의미한다.)
[useEffect 훅의 기본 형태]
import React, {useEffect} from 'react'
useEffect(
(이펙트 함수)
return {
(클린업 함수)
}
}, [의존값]);
// 이펙트 함수 호출시점 : 컴포넌트가 처음 마운트될 때, 의존값으로 주어진 값이 변경될 때
// 클린업 함수 호출시점 : 이펙트 함수가 호출되기 전, 컴포넌트가 언마운트될때 각각 클린업이 호출된다.
// 의존값 배열이 비어 있으면 최초 마운트 시에만 이펙트를 호출한다.
// 의존값이 존재하지 않으면 컴포넌트가 렌더링될 때마다 이펙트를 호출한다.
아직은 뭐가 뭔지 어질어질할테니 먼저 간단한 예제를 통해 이펙트를 살펴보자.
import React, { useState, useEffect } from "react";
function UseEffect() {
const [count, setCount] = useState(0)
useEffect(() => {
console.log("effect");
}, []);
console.log("render");
return (
<>
<div>
<button onClick={() => setCount((prev) => prev + 1)}>+</button>
<div>{count}</div>
</div>
</>
);
}
export default UseEffect;
버튼을 누르면 숫자가 올라가는 간단한 카운터 코드의 동작을 정리해 보자.
버튼을 누를 때마다 count 상태값이 업데이트됨과 동시에 함수 컴포넌트가 새로 호출되어 "render" 가 콘솔에 출력된다.
그러나 useEffect
의 이펙트 함수는 단 한 번만 호출되는 것을 확인할 수 있는데, 이것이 useEffect
를 사용하는 첫 번째 이유다.
채팅 서버에 연결한다던가 등 컴포넌트가 마운트되면서 처음 1회만 수행되어야 하는 동작이 필요할 때 useEffect
를 사용할 수 있으며 컴포넌트가 마운트될 때 뿐만 아니라 원하는 값이 변경될 때도 이펙트를 호출할 수도 있다.
한 가지 주의할 점이라면 이펙트 함수는 언제나 컴포넌트 렌더링이 모두 끝난 다음에 실행된다.
import React, { useState, useEffect } from "react";
function UseEffect() {
const [srcType, setSrcType] = useState("posts");
const [items, setItems] = useState([]);
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/${srcType}`)
.then((res) => res.json())
.then((data) => setItems(data));
}, [srcType]);
return (
<>
<div>
<button onClick={() => setSrcType("posts")}>Posts</button>
<button onClick={() => setSrcType("users")}>Users</button>
<button onClick={() => setSrcType("comments")}>Comments</button>
</div>
<h1>{srcType}</h1>
{items.map((item) => {
return <pre>{JSON.stringify(item)}</pre>;
})}
{}
</>
);
}
export default UseEffect;
이 코드는 컴포넌트가 최초 마운트될 때 한 번, srcType
값이 변경될 때마다 이펙트를 호출해 서버로부터 값을 불러온다.
만약 서버로부터 값을 단 한 번만 불러와야만 한다면 위에서 했듯 의존값 배열을 비워 주면 된다.
다음은 클린업 함수로, 클린업 함수는 이펙트가 호출되기 전과 컴포넌트가 언마운트될 때 호출되면서 이전 이펙트로 인한 결과를 정리하는 역할이다.
(* 단 컴포넌트가 마운트되면서 호출되는 이펙트는 이전 이펙트가 없으므로 이 때는 호출되지 않는다.)
import React, { useState, useEffect } from "react";
function UseEffect() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("count increased!");
return () => {
console.log("Run Cleanup");
};
}, [count]);
return (
<>
<div>
<button onClick={() => setCount((prev) => prev + 1)}>+</button>
<div>{count}</div>
</div>
</>
);
}
export default UseEffect;
+ 버튼을 누르면 숫자가 올라가는 카운터 예제다.
버튼을 누를 때마다 "Run Cleanup" 문구가 먼저 출력되고 이펙트가 호출되는 것을 확인할 수 있다.
import React, { useState, useEffect } from "react";
function UseEffect2() {
const [windowWitdh, setWindowWitdh] = useState(window.innerWidth);
const handleResize = () => {
setWindowWitdh(window.innerWidth);
};
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return <div>{windowWitdh}</div>;
}
export default UseEffect2;
이렇게 마운트 시점에 이벤트 리스너를 추가하고 언마운트될때 이벤트 리스너를 제거하는 식으로도 클린업 함수를 활용할 수 있다.
비록 눈으로는 확인하기 힘들지만 소켓에서 연결을 끊는다던지 확실한 마무리가 필요한 작업을 수행할 때 클린업을 활용한다.
'🎨 프론트엔드 > React.js' 카테고리의 다른 글
useContext 훅에 대하여 (0) | 2021.01.05 |
---|---|
useRef 훅에 대하여 (1) | 2021.01.01 |
useMemo 훅에 대하여 (0) | 2020.12.30 |
Portal 사용하기 (0) | 2020.12.28 |
useState 훅에 대하여 (0) | 2020.12.28 |