리액트에서 컴포넌트의 라이프사이클은 컴포넌트가 생성되고, 업데이트되며, 마지막으로 소멸하는 일련의 과정을 말합니다. 이 과정에서 리액트는 특정 시점마다 개발자가 작업을 수행할 수 있는 **후크(hooks)**를 제공합니다. 라이프사이클은 컴포넌트가 DOM에 렌더링되고 난 후부터, 상태나 props의 변경으로 인해 다시 렌더링될 때, 컴포넌트가 제거될 때까지의 일련의 단계를 포함합니다.
1. 컴포넌트의 라이프사이클 단계
리액트 컴포넌트는 크게 세 가지 주요 단계로 나눌 수 있습니다:
1. 마운트(Mount): 컴포넌트가 생성되어 DOM에 추가되는 시점.
2. 업데이트(Update): 컴포넌트의 상태나 props가 변경되어 다시 렌더링되는 시점.
3. 언마운트(Unmount): 컴포넌트가 DOM에서 제거되는 시점.
2. 함수형 컴포넌트의 라이프사이클 (Hooks 기반)
리액트에서 함수형 컴포넌트는 **훅(Hooks)**을 통해 라이프사이클과 관련된 작업을 수행할 수 있습니다. 특히, useEffect 훅을 사용하여 컴포넌트의 라이프사이클을 관리할 수 있습니다. useEffect는 마운트, 업데이트, 언마운트와 같은 라이프사이클 단계에서 특정 동작을 수행할 수 있도록 합니다.
useEffect 훅의 기본 구조:
import React, { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
// 이 코드는 컴포넌트가 마운트될 때 실행됩니다.
return () => {
// 이 코드는 컴포넌트가 언마운트될 때 실행됩니다.
};
}, []); // 빈 배열([])은 의존성(dependency)이 없음을 의미하며, 마운트와 언마운트 시에만 동작하게 만듭니다.
return <div>My Component</div>;
}
3. 마운트(Mount) 단계
마운트는 컴포넌트가 처음으로 DOM에 추가되는 시점입니다. 함수형 컴포넌트에서는 useEffect 훅을 사용해 마운트 시점에 특정 작업을 수행할 수 있습니다.
예시:
import React, { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
console.log("컴포넌트가 마운트되었습니다.");
// 여기서 API 호출, 초기 데이터 로드 등을 수행할 수 있습니다.
}, []); // 의존성 배열이 비어 있으면 마운트 시에만 실행됩니다.
return <div>My Component</div>;
}
마운트 단계에서 주로 하는 작업:
• API 호출: 초기 데이터를 불러오거나 서버와 통신하는 작업.
• 초기 상태 설정: 컴포넌트가 처음 렌더링될 때 필요한 초기 상태를 설정하는 작업.
• 타이머 또는 이벤트 리스너 설정: 타이머, 이벤트 리스너 등을 설정하는 작업.
4. 업데이트(Update) 단계
컴포넌트의 상태(state) 또는 **props**가 변경되면 컴포넌트는 다시 렌더링됩니다. 이 과정을 업데이트라고 하며, 함수형 컴포넌트에서는 **useEffect**의 **의존성 배열(dependencies array)**을 통해 특정 값이 변경될 때마다 특정 작업을 수행할 수 있습니다.
useEffect와 의존성 배열을 통한 업데이트 처리:
import React, { useState, useEffect } from 'react';
function MyComponent({ someProp }) {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`컴포넌트가 업데이트되었습니다. 현재 count 값: ${count}`);
// count 값이 변경될 때마다 이 코드가 실행됩니다.
}, [count]); // count가 변경될 때마다 effect가 실행됨
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
업데이트 단계에서 주로 하는 작업:
• 상태가 변경되면 발생하는 동작 처리: 컴포넌트가 렌더링될 때마다 상태를 기반으로 추가 작업을 처리할 수 있습니다.
• 새로운 props 값 처리: 부모 컴포넌트로부터 전달된 props가 변경될 때마다 특정 작업을 수행할 수 있습니다.
• DOM 업데이트 이후 동작 처리: 컴포넌트가 다시 렌더링된 후 특정 DOM 요소에 대해 작업을 수행할 수 있습니다.
5. 언마운트(Unmount) 단계
언마운트는 컴포넌트가 DOM에서 제거되는 시점을 말합니다. 이 단계에서 컴포넌트가 더 이상 사용되지 않으므로, 컴포넌트에 의해 설정된 타이머나 이벤트 리스너 등을 **정리(clean up)**해야 합니다. 이 작업은 메모리 누수를 방지하기 위해 매우 중요합니다.
함수형 컴포넌트에서는 useEffect의 **정리 함수(cleanup function)**를 사용하여 언마운트 시 작업을 수행할 수 있습니다.
언마운트 처리 예시:
import React, { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
const timer = setInterval(() => {
console.log("타이머 실행 중...");
}, 1000);
return () => {
// 컴포넌트가 언마운트될 때 타이머를 정리합니다.
clearInterval(timer);
console.log("컴포넌트가 언마운트되었습니다.");
};
}, []);
return <div>My Component</div>;
}
언마운트 단계에서 주로 하는 작업:
• 타이머 또는 이벤트 리스너 정리: setInterval 또는 setTimeout으로 생성된 타이머를 제거하거나, DOM 이벤트 리스너를 해제하는 작업.
• 비동기 작업 취소: 비동기 API 호출이 완료되기 전에 컴포넌트가 언마운트되면, 해당 작업을 취소하는 것이 좋습니다.
• 외부 라이브러리 정리: 예를 들어, 외부 라이브러리나 플러그인에서 설정된 리소스를 해제하는 작업.
6. useEffect의 동작 방식 정리
• useEffect(() => { ... }, []): 이 형태의 useEffect는 마운트 시 한 번만 실행됩니다.
• useEffect(() => { ... }, [dependency]): 이 형태의 useEffect는 특정 의존성 값(dependency)이 변경될 때마다 실행됩니다.
• useEffect(() => { return () => { ... } }, []): 이 형태의 useEffect는 언마운트 시 정리 작업을 수행합니다.
7. 컴포넌트 라이프사이클의 활용 예
1) API 데이터 로딩:
• 컴포넌트가 처음 렌더링될 때 API를 호출하여 데이터를 불러옵니다. 데이터를 불러오는 동안 로딩 상태를 유지하고, 데이터를 받아오면 상태를 업데이트하여 화면에 표시합니다.
import React, { useEffect, useState } from 'react';
function DataFetchingComponent() {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchData() {
const response = await fetch("https://api.example.com/data");
const result = await response.json();
setData(result);
}
fetchData();
}, []); // 마운트 시에만 실행
return (
<div>
{data ? <pre>{JSON.stringify(data, null, 2)}</pre> : <p>Loading...</p>}
</div>
);
}
2) 윈도우 리사이즈 이벤트 처리:
• 컴포넌트가 마운트되었을 때 윈도우 리사이즈 이벤트를 감지하고, 컴포넌트가 언마운트될 때 이벤트 리스너를 해제합니다.
import React, { useState, useEffect } from 'react';
function WindowSizeComponent() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => {
setWindowWidth(window.innerWidth);
};
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize); // 정리 작업
};
}, []); // 마운트 시에만 실행
return <p>Window width: {windowWidth}px</p>;
}
설명:
• 마운트 시 useEffect를 사용하여 윈도우 리사이즈 이벤트 리스너를 추가하고, 창 크기가 변경될 때마다 handleResize가 실행되어 windowWidth 상태를 업데이트합니다.
• 언마운트 시에는 이벤트 리스너를 제거하는 정리 작업을 수행하여 메모리 누수를 방지합니다.
8. 컴포넌트 라이프사이클의 요약
리액트 컴포넌트는 마운트, 업데이트, 언마운트의 세 가지 주요 라이프사이클 단계를 거칩니다. 함수형 컴포넌트에서는 주로 useEffect 훅을 사용하여 이 라이프사이클을 처리하며, 각 단계에서 특정 작업을 수행할 수 있습니다.
• 마운트(Mount): 컴포넌트가 DOM에 처음 추가될 때 발생하며, 이 단계에서 주로 초기 데이터 로딩, 타이머 설정 등을 수행합니다.
• 업데이트(Update): props나 state가 변경될 때 발생하며, 이 단계에서 컴포넌트가 다시 렌더링되면서 상태나 props 변화에 따른 작업을 수행합니다.
• 언마운트(Unmount): 컴포넌트가 DOM에서 제거될 때 발생하며, 메모리 누수를 방지하기 위해 타이머, 이벤트 리스너 등을 정리하는 작업을 수행합니다.
함수형 컴포넌트에서는 **useEffect**를 사용하여 마운트, 업데이트, 언마운트 시점에 작업을 처리할 수 있으며, 이를 통해 컴포넌트의 생명주기 전반에 걸쳐 필요한 동작을 관리할 수 있습니다.
이 라이프사이클 관리는 리액트 애플리케이션의 상태 관리, 비동기 데이터 로딩, 성능 최적화 등의 다양한 작업에 매우 중요합니다.
'React' 카테고리의 다른 글
[React] useEffect 훅, 의존성 배열 (0) | 2024.09.13 |
---|---|
[React] Hooks (0) | 2024.09.13 |
[React] 리액트 상태(State)와 자바스크립트의 비동기 차이점 (1) | 2024.09.13 |
[React] State (0) | 2024.09.13 |
[React] Props (0) | 2024.09.13 |