728x90
반응형
Component Lifecycle 톺아보기 🎢
리액트에서 컴포넌트는 생명주기(Lifecycle)를 가집니다. 컴포넌트는 태어나고(Mounting), 살아가며(Update), 마침내 떠나죠(Unmounting). 리액트의 라이프사이클 메서드와 훅을 이해하면, 컴포넌트의 상태 변화와 동작을 제어할 수 있습니다. 리액트 개발자라면 반드시 이해해야 하는 개념! 함께 시작해볼까요? 🚀
리액트 라이프사이클, 왜 중요할까? 🤔
리액트 컴포넌트는 여러 단계에서 특정 작업을 수행할 기회를 제공합니다. 예를 들어:
- 컴포넌트가 화면에 나타날 때 데이터를 로드하거나,
- 상태가 변경될 때 DOM을 업데이트하거나,
- 컴포넌트가 사라질 때 리소스를 정리할 수 있죠
이 과정은 크게 세 단계로 나뉩니다:
- 마운트(Mounting): 컴포넌트가 DOM에 삽입될 때
- 업데이트(Updating): 컴포넌트의 상태(state)나 props가 변경될 때
- 언마운트(Unmounting): 컴포넌트가 DOM에서 제거될 때
클래스형 컴포넌트와 라이프사이클 메서드 🏛️
리액트에서는 클래스형 컴포넌트가 라이프사이클 메서드를 통해 생명주기를 제어할 수 있습니다.
1. 마운트(Mounting) 단계
컴포넌트가 DOM에 추가되는 과정입니다. 이 과정에서 호출되는 주요 메서드는 다음과 같습니다:
- constructor: 컴포넌트를 초기화하는 데 사용
- static getDerivedStateFromProps: props로부터 state를 동기화하고 싶을 때 사용
- render: JSX를 반환하며, 컴포넌트를 화면에 렌더링
- componentDidMount: DOM이 생성되고 나서 호출
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { data: null };
console.log("1. Constructor: 컴포넌트 초기화");
}
static getDerivedStateFromProps(props, state) {
console.log("2. getDerivedStateFromProps: props로 state 설정");
return null; // 기본적으로 state를 변경하지 않을 때 null 반환
}
componentDidMount() {
console.log("4. componentDidMount: DOM이 준비된 후 호출");
// API 호출 예시
fetch("https://api.example.com/data")
.then((response) => response.json())
.then((data) => this.setState({ data }));
}
render() {
console.log("3. Render: JSX 반환");
return <div>My Component</div>;
}
}
2. 업데이트(Updating) 단계
컴포넌트의 props 또는 state가 변경될 때 실행됩니다. 이 과정에서 호출되는 주요 메서드는 다음과 같습니다:
- static getDerivedStateFromProps: 마운트와 업데이트 모두 호출
- shouldComponentUpdate: 리렌더링 여부를 결정
- render: 변경된 내용을 기반으로 JSX를 반환
- getSnapshotBeforeUpdate: DOM 업데이트 직전 상태를 캡처할 때 사용
- componentDidUpdate: DOM 업데이트 후 호출
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
shouldComponentUpdate(nextProps, nextState) {
console.log("1. shouldComponentUpdate: 리렌더링 여부 결정");
return nextState.count !== this.state.count; // count가 변경될 때만 렌더링
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("2. getSnapshotBeforeUpdate: DOM 변경 전 캡처");
return { prevCount: prevState.count };
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("3. componentDidUpdate: DOM 변경 후 호출");
console.log("이전 count:", snapshot.prevCount);
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}
3. 언마운트(Unmounting) 단계
컴포넌트가 DOM에서 제거되는 과정입니다.
- componentWillUnmount: 컴포넌트가 DOM에서 제거되기 직전에 호출
class MyComponent extends React.Component {
componentWillUnmount() {
console.log("componentWillUnmount: 컴포넌트가 제거됩니다.");
// 예: 타이머 정리
clearInterval(this.timer);
}
render() {
return <div>Goodbye, World!</div>;
}
}
함수형 컴포넌트와 훅(Hooks) 🪝
React Hooks가 등장하면서, 함수형 컴포넌트에서도 라이프사이클을 제어할 수 있게 되었습니다. 주요 훅은 다음과 같습니다:
- useState: 상태 관리
- useEffect: 사이드 이펙트를 처리
- useRef: DOM 요소나 값 참조
useEffect로 라이프사이클 관리하기
import React, { useState, useEffect } from "react";
function MyComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Component Mounted or Updated!");
// Cleanup 함수 (언마운트 시 실행)
return () => {
console.log("Component Unmounted!");
};
}, [count]); // count가 변경될 때마다 실행
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
리액트의 라이프사이클 정리 🗂️
단계 | 클래스형 메서드 | 함수형 훅 | 설명 |
마운트 | constructor | 초기값 설정 | 컴포넌트 초기화 |
getDerivedStateFromProps | 없음 | props로 state를 동기화 | |
render | JSX 반환 | UI 렌더링 | |
componentDidMount | useEffect | DOM 생성 후 작업 | |
업데이트 | getDerivedStateFromProps | 없음 | props로 state를 동기화 |
shouldComponentUpdate | 없음 | 리렌더링 여부 결정 | |
render | JSX 반환 | UI 렌더링 | |
getSnapshotBeforeUpdate | 없음 | DOM 변경 전 캡처 | |
componentDidUpdate | useEffect | DOM 변경 후 작업 | |
언마운트 | componentWillUnmount | useEffect | 컴포넌트 제거 직전 작업 |
실전 예제: 데이터 가져오기와 정리하기 🛠️
아래는 API 호출과 데이터 정리를 포함한 컴포넌트 라이프사이클 관리 예제입니다.
import React, { useState, useEffect } from "react";
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchData() {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
const data = await response.json();
setUsers(data);
setLoading(false);
}
fetchData();
// Cleanup: 예시로 타이머 정리 추가
return () => {
console.log("Cleanup on unmount");
};
}, []);
if (loading) {
return <p>Loading...</p>;
}
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
마무리: 리액트 라이프사이클 완벽 이해 🎉
리액트의 라이프사이클은 컴포넌트의 상태와 동작을 관리하는 데 매우 중요합니다. 클래스형 메서드와 훅을 상황에 맞게 활용하면, 성능 최적화와 깔끔한 코드 유지가 가능합니다.
이제 리액트 컴포넌트의 “삶과 죽음”을 지휘할 준비가 되셨나용?
🌷전설의 개발자가 되어봅시당! 🌷
728x90
반응형
'Front-end > Javascript' 카테고리의 다른 글
[Javascript] callback의 bucket relay: 협업의 예술 🎨 (0) | 2024.12.30 |
---|---|
[Javascript] 템플릿 리터럴(Template Literal): 자바스크립트 문자열의 진화 🌟 (0) | 2024.12.17 |
자바스크립트의 filter: 데이터를 깔끔하게 추려내는 요술사 ✨ (0) | 2024.12.03 |
자바스크립트의 concat: 배열 합치기의 마법사 🧙♂️ (0) | 2024.12.02 |
자바스크립트의 map 함수: 알고 보면 개발자의 베프 💡 (0) | 2024.12.01 |