Effect Hook
을 통해 클래스 방식의 라이프사이클 역활을 담당
이전 포스팅에서 특정 상황에 이벤트를 발생시키는 클래스 방식의 Lifecycle
에 대해 설명했다.
Hook
에서는 Lifecycle
이 존재하지 않지만 Effect Hook
, 즉 useEffect
를 통해 흉내낼수 있다.
즉 useEffect
는 클래스 방식의 Lifecycle APIs
를 하나로 통합한다.
useEffect
는 함수, 배열 2가지의 인자를 받아 사용하는데 각각의 인자는 다음과 같이 Lifecycle
의 역활을 담당한다.
첫번째 인자 함수는
componentDidMount
의 역활을 담당
첫번째 인자 함수의return
값은componentWillUnmount
의 역활을 담당
두번째 인자 배열은componentDidUpdate
의 역활을 담당
useEffect(() => {
console.log("componentDidMount!!");
return () => {
console.log("componentWillUnmount!!");
}
}, ["componentDidUpdate"]);
Hook
에서의 componentDidMount
는 useEffect
의 첫번째 인자 함수가 담당하며 컴포넌트 최초 렌더링시 실행된다.
아래 예제를 보면 최초 렌더링 이 후 콜솔에 결과가 찍히지 않는 것을 확인할 수 있다.
import React, { useState, useEffect } from "react";
const ShoppingList = () => {
const [count, setCount] = useState(0);
const onClickBtn = () => {
setCount(count + 1);
}
useEffect(() => {
console.log("첫 랜더링!!");
}, []);
return (
<div>
<p>맛있는 사과 {count}개 구매</p>
<button onClick={onClickBtn}>+</button>
</div>
);
};
export default ShoppingList;
Hook
에서의 componentWillUnmount
는 useEffect
의 첫번째 인자 함수의 return
이 담당하며 해당 컴포넌트가 제거되기 직전 실행된다.
클래스 방식과 마찬가지로 주로 componentDidMount
에서 등록한 이벤트를 삭제해주는 역활로 사용된다.
이러한 역활을 담당하는 함수를 cleanup
함수라고 부르며 만약 이벤트를 제거해주지 않는다면 컴포넌트가 리렌더링 될 때마다 새로운 이벤트가 바인딩되어 메모리 누수가 발생할 수 있다.
import React, { useState, useEffect } from "react";
const ShoppingList = () => {
const [count, setCount] = useState(0);
const onClickBtn = () => {
setCount(count + 1);
}
useEffect(() => {
console.log("첫 랜더링!!");
interval = setInterval(() => {
console.log('이벤트 발생!!');
}, 1000);
return () => {
clearInterval(interval);
}
}, []);
return (
<div>
<p>맛있는 사과 {count}개 구매</p>
<button onClick={onClickBtn}>+</button>
</div>
);
};
export default ShoppingList;
Hook
에서의 componentDidUpdate
는 useEffect
의 두번째 인자 배열이 담당하며 특정 값이 변경되는 경우에만 실행된다.
아래 예제를 보면 최초 렌더링 이 후 state
가 변경될 때마다 결과가 콘솔에 찍히는 것을 확인할 수 있다.
import React, { useState, useEffect } from "react";
const ShoppingList = () => {
const [count, setCount] = useState(0);
const onClickBtn = () => {
setCount(count + 1);
}
useEffect(() => {
console.log("count의 값은 " + count);
}, [count]);
return (
<div>
<p>맛있는 사과 {count}개 구매</p>
<button onClick={onClickBtn}>+</button>
</div>
);
};
export default ShoppingList;
UserInfo
컴포넌트는 name
, age
, email
총 3가지의 state
로 회원의 정보를 관리한다고 가정해보겠다.
이 때 Lifecycle
과 Effect Hook
은 다음과 같이 각각 다른 방법으로 state
를 관리한다.
import React, { useState, useEffect } from "react";
const UserInfo = () => {
const [name, setName] = useState('');
const [age, setAge] = useState(0);
const [email, setEmail] = useState('');
return (
<div>
<p>유저의 이름 : {name}</p>
<p>유저의 나이 : {age}</p>
<p>유저의 이메일 : {email}</p>
</div>
);
};
export default UserInfo;
클래스 방식은 아래 표와 같이 하나의 Lifecycle
이 모든 state를 각각 관리한다.
name | age | ||
---|---|---|---|
componentDidMount | --------------------> | --------------------> | --------------------> |
componentDidMount | --------------------> | --------------------> | --------------------> |
componentDidMount | --------------------> | --------------------> | --------------------> |
Effect Hook
은 아래 표와 같이 각각의 state
를 독립적으로 관리한다.
name | age | ||
---|---|---|---|
useEffect1 | useEffect1 관리 | ||
useEffect2 | useEffect2 관리 | ||
useEffect3 | useEffect3 관리 |