생명주기( lifecycle ) : 프로그램이 실행되고 종료될 때 까지의 과정
리액트의 컴포넌트도 Lifecycle을 갖는다.
1. 탄생 → 화면에 나타나는 것 : 컴포넌트 mount ex) 초기화 작업
2. 변화 → 업데이트( 리렌더 ) : update * 컴포넌트가 변화하는 순간 ex) 예외 처리 작업
3. 죽음 → 화면에서 사라짐 : 컴포넌트 unmount ex) 메모리 정리 작업
컴포넌트의 lifecycle을 제어한다는 것은 컴포넌트가 탄생 → 변화 → 죽음 과정동안 각각 필요한 작업을
수행시켜주면 된다는 의미이다.
리액트는 기본적으로 lifecycle마다 실행할 수 있는 메소드를 가지고 있다.

1. componentDidMount : 컴포넌트가 mount 되는 순간에 어떠한 기능을 수행할 수 있도록 되어있는 메소드
2. componentDidUpdate : 컴포넌트가 변화하는 순간에 사용할 수 있는 메소드
3. componentWillUnmount : 컴포넌트가 화면에서 사라지는 unmount 이전에 호출해서 사용할 수 있는 메소드
하지만 이러한 메소드들은 클래스형 컴포넌트에서 밖에 사용할 수 밖에 없다. 원래는 함수형 컴포넌트에서는
state도 사용할 수 없다.
* 함수 형태로 제작하는 컴포넌트는 함수형 컴포넌트
use 키워드를 앞에 붙여서 클래스 컴포넌트가 근본적으로 가지고 있는 기능을 함수형 컴포넌트에서 Hooking해서
사용할 수 있는 기능을 React Hooks라 부른다. ex) useState, useEffect, useRef
→ 원래 state 같은 기능들은 함수형 컴포넌트가 사용할 수 없지만 React Hooks가 개발되면서 함수형 컴포넌트에서도
use 키워드를 이용해 함수처럼 사용할 수 있게 됐다.
React Hooks : 함수형 컴포넌트에서 클래스형 컴포넌트의 기능을 가져와서 사용할 수 있도록 해주는 기능
→ React Hooks는 클래스형 컴포넌트의 길어지는 코드 길이 문제, 중복 코드, 가독성 문제 등을 해결하기 위해 등장
클래스형 컴포넌트는 함수형 컴포넌트보다 같은 기능을 구현하는데 비교적 코드가 길고 복잡하며 중복 코드를 많이
사용한다. 최근에는 함수형 컴포넌트를 많이 사용하려는 추세이다.
useEffect : 리액트의 lifecycle을 제어하는 메소드를 가져올 수 있는 기능
리엑트의 함수형 컴포넌트에서 lifecycle을 제어하기 위해 useEffect React Hooks를 사용한다.
import React, { useEffect } from "react";
useEffect(()=>{
//todo → callback 함수
},[]);
useEffect는 2개의 파라미터를 전달하게 된다. 첫번째 파라미터는 콜백 함수이고, 두번째 파라미터는 Dependency
Array( 의존성 배열 )을 전달해준다. 두번째 파라미터인 Devs안에 들어있는 값이 하나라도 변화하면 첫번째 파라미터인
콜백함수가 수행이 된다.
→ 두번째 파라미터인 Devs 배열에 자꾸 변화하는 어떠한 값을 넣어둔다면 첫번째 파라미터인 콜백함수가 그 값이
변할 때 마다 계속 수행이 된다.
[ 컴포넌트가 mount 되는 시점을 제어해보기 ]
LifeCycle.js
import React, { useState, useEffect } from "react";
const LifeCycle = () => {
const [count, setCount] = useState(0); // 카운터 사용
const [text, setText] = useState(""); //input에 사용
useEffect(() => {
console.log("mount");
}, []);
return (
<div style={{ padding: 20 }}>
<div>
{count}
<button
onClick={() => {
setCount(count + 1);
}}
>
+
</button>
</div>
<div>
<input
value={text}
onChange={(e) => {
setText(e.target.value);
}}
></input>
</div>
</div>
);
};
export default LifeCycle;
리액트를 실행시키고 콘솔을 확인해보면 mount가 찍혀있는 것을 확인할 수 있다. 즉, 컴포넌트가 mount 되는 순간에
console.log("mount")가 수행이 되었다. mount 되는 시점에만 콜백함수가 수행되는지 확인해보기 위해 버튼을
클릭해 count의 수를 증가해볼 경우, 컴포넌트가 리랜더링이 되는데 useEffect에 빈배열을 전달하게 되면 콜백함수는
컴포넌트가 mount되는 순간에만 작동하기 때문에 콘솔에 더이상 아무것도 출력되지 않는 것을 확인할 수 있다.
즉, 컴포넌트가 mount 되는 순간에 무엇을 작업하고 싶다면 useEffect()의 두번째 파라미터인 devs에 빈배열을
전달해준 다음에 콜백함수에 작업하고 싶은 내용을 전달해주면 된다.
[ 컴포넌트가 업데이트 되는 순간을 제어해보기 ]
컴포넌트는 state가 변경되거나, 부모 컴포넌트에게서 내려받은 props가 변경되거나, 부모 컴포넌트가 리랜더링될
경우 자기 자신도 리랜더링 된다. 리랜더링이 된다는 의미는 컴포넌트가 업데이트되는 의미와 동일하다.
state를 변경하는 순간인 컴포넌트를 업데이트하는 순간에 useEffect를 사용해서 제어하면 된다.
업데이트를 하는 useEffect에는 두번째 파라미터에 Dependency Array를 전달해주지 않으면 된다.
useEffect(() => {
console.log("Update");
});
버튼을 클릭해서 count를 증가시키거나, input에 값을 입력할 경우 콘솔에 Update가 출력되는 것을 확인할 수 있다.
즉, 컴포넌트가 업데이트 되는 순간에 하고 싶은 작업이 있다면 useEffect를 사용하면 된다.
[ useEffect 두번째 파라미터에 값을 전달해보기 ]
useEffect의 두번째 파라미터인 Dependency Array의 값이 변하게 되면 그 순간 콜백 함수가 수행이 된다.
useEffect(() => {}, [count]);
콜백함수는 count state가 변화하는 순간, 다시 호출이 된다.
useEffect(() => {
console.log(`count is update : ${count}`);
}, [count]);
useEffect(() => {
console.log(`text is update : ${text}`);
}, [text]);

Dependency Array를 잘 활용한다면 감지하고 싶은 값만 감지해서 그 값이 변화하는 순간에만 콜백함수가 수행되도록
코드를 작성할 수 있다.
useEffect(() => {
console.log(`count is update : ${count}`);
if (count > 5) {
alert("count가 5를 초과 ( 1로 초기화 됩니다.)");
setCount(1);
}
}, [count]);

[ 컴포넌트가 unmount되는 순간을 제어해보기 ]
* 하나의 파일에 두 개의 컴포넌트를 생성해도 문제가 발생하지 않는다.
UnmountTest 컴포넌트는 isVisivible state가 true일 때만 렌더되도록 코드를 작성하기 → 단락회로평가 사용
* 단락회로평가 : 왼쪽에서 오른쪽으로 연산하게 되는 논리 연산자의 연산 순서를 이용하는 방법
→ 피연산자 중에 뒤에 있는 피연산자를 확인할 필요 없이 바로 연산을 끝내는 것
import React, { useState, useEffect } from "react";
const UnmountTest = () => {
return <div>Unmount Testing Component</div>;
};
const LifeCycle = () => {
const [isVisivible, setIsVisible] = useState(false);
const toggle = () => {
setIsVisible(!isVisivible);
};
return (
<div style={{ padding: 20 }}>
<button onClick={toggle}>ON/OFF</button>
{isVisivible && <UnmountTest />}
</div>
);
};
export default LifeCycle;
isVisible 값이 true가 되면 단락회로평가를 수행할 수 없다. &&일 경우 뒤에도 확인해야하기 때문이다.
뒤에 온 <UnmountTest> 컴포넌트를 확인하고 그 컴포넌트가 Truty라면 <UnmountTest> 컴포넌트를 반환하게 된다.
→ 결론적으로 isVisible이 true라면 <UnmountTest> 컴포넌트가 반환이 되서 화면에 랜더링된다. 반대로 isVisible이
false라면 이미 {}안에 값이 false이기 때문에 단락회로 평가에 의해 <UnmountTest> 컴포넌트도 화면에 랜더링되지
않는다. 단락회로 평가를 통해 뒤에 있는 값을 랜더할지 안할지 결정할 수 있다.


아무것도 없는 상태에서 버튼을 클릭하면 Unmount Testing Component가 출력이 되고, 버튼을 다시 클릭할 경우
해당 문구는 사라지는 것을 확인할 수 있다.
UnmountTest 컴포넌트에 useEffect를 사용해서 컴포넌트가 unmount가 되는 순간을 제어해보기
→ unmount의 경우는 mount를 제어하는 useEffect에 전달되는 콜백함수가 함수를 리턴하게 하면 된다.
그 리턴은 unmount 시점에 실행되게 된다.
const UnmountTest = () => {
useEffect(() => {
console.log("mount");
return () => {
//unmount 시점에 실행되게 한다.
console.log("unmount");
};
}, []);
return <div>Unmount Testing Component</div>;
};

import React, { useState, useEffect } from "react";
const UnmountTest = () => {
useEffect(() => {
console.log("mount");
return () => {
//unmount 시점에 실행되게 한다.
console.log("unmount");
};
}, []);
return <div>Unmount Testing Component</div>;
};
const LifeCycle = () => {
const [isVisivible, setIsVisible] = useState(false);
const toggle = () => {
setIsVisible(!isVisivible);
};
return (
<div style={{ padding: 20 }}>
<button onClick={toggle}>ON/OFF</button>
{isVisivible && <UnmountTest />}
</div>
);
};
export default LifeCycle;'Front-End > React' 카테고리의 다른 글
| [ React ] React 기본 ⑥ React Developer Tools (0) | 2022.10.15 |
|---|---|
| [ React ] React 기본 ⑤ React에서 API 호출하기 (0) | 2022.10.14 |
| [ React ] React 기본 ③ React에서 배열 사용하기 - 4. 리스트 데이터 수정하기 (0) | 2022.10.01 |
| [ React ] React 기본 ③ React에서 배열 사용하기 - 3. 리스트 데이터 삭제하기 (0) | 2022.10.01 |
| [ React ] React 기본 ③ React에서 배열 사용하기 - 2. 리스트 데이터 추가하기 (0) | 2022.09.29 |