리액트 생명주기 공부하는 동안 내 마음 ↓
그래도 해야지.. 어떡해.
1. 생명주기란 ?
2. useEffect()?
3. 언제 주로 필요로 하는가
3-1 데이터 받아올 때,
3-2 이벤트 핸들러 사용시,
3-3 타이머 함수 사용시,
🎠 생명주기(Lifecycle)란?
컴포넌트는 태어나고(mount), 살고(update), 사라져(unmount).
React는 이걸 자동으로 관리해줘. 우리가 여기에 중간중간 개입할 수 있는 타이밍을 주는 거야.
→ 바로 그 타이밍이 생명주기!
와닿지가 않는 생명주기란 것..
▾아래에 쉽게 한번 정리 해보았습니다.▾
리액트 공부하기 - 생명주기를 쉽게 이해해보자. (개인적인 견해를 덭붙여서)
생명주기란 말.. 너무 와닿지 않아 너.. 생명 주기 때문에 어려움을 겪고 계신 여러분들,, 제 글을 보며 조금 도움이 되길 바랍니다... 그냥 생명주기라고 하지말고 관리타이밍 이라고 이
creamymood.tistory.com
🎠 useEffect 란?
리액트(React)에서 useEffect라는 훅(hook)으로써 컴포넌트의 생명주기(lifecycle)와 타이밍을 관리한다.
useEffect는 쉽게 말하면 “이 타이밍에 이 코드를 실행해줘~” 하고 React에게 알려주는 거야.
그래서 핵심은?
✨ 렌더링 타이밍에 맞춰 실행을 컨트롤할 수 있는 도구
✨ fetch 같은 비동기 작업이나 DOM 조작, 타이머 설정 등을 여기에 넣는 거야
→ 랜더링 후에 어떤 작업을 실행할지 정하는 것 !
쉽게 말하면 ?
🕊️ "컴포넌트가 렌더링된 다음에 이 작업 해줘!"
예를 들면...
데이터를 가져오기 (fetch)
타이머 설정 (setTimeout)
외부 라이브러리 연결하기 (예: chart, map 등)
DOM 조작하기 (스크롤 위치 조정 등)
이런 **“부수 효과(side effect)”**를 실행하는 게 목적이다.
아래 핵심 포인트를 살펴본다면 조금 이해가 쉬울 것 같다.
🎠 언제 사용될까 ? 왜 필요할까?
❶. 서버에서 데이터를 받아올 때, 주로 필요하다.
패치 함수를 사용할 때를 생각해보자
패치 함수란 ?
보통 서버에 데이터를 요청할 때 사용하는 함수를 말해. 특히 fetch()라는 기본적인 Web API를 사용하는 경우가 많아.
예를 들어, 서버에서 데이터를 가져와서 화면에 보여주고 싶을 때 이렇게 사용
useEffect(() => {
fetch('https://api.example.com/data') // 서버에 요청
.then(response => response.json()) // 응답을 JSON으로 파싱
.then(data => {
setData(data); // 받아온 데이터를 상태로 저장
})
.catch(error => {
console.error('에러 발생:', error);
});
}, []);
정리하자면:
→ **패치 함수(fetch function)**는 데이터를 가져오는 역할을 한다.
주로 API 요청을 보낼 때 사용하고, 리액트에선 보통 useEffect() 안에서 쓰인다.
fetch()는 브라우저에서 제공하는 함수라 별도 설치는 필요 없다.
→ "패치 함수(fetch function)는 비동기 작업이다" 이기 때문에
작업이 바로 끝나지 않고, 시간이 좀 걸릴 수 있어서 나중에 결과를 알려주는 방식이다.
그래서 다음과 같은 상황은 데이터를 화면에 표시하려고 하는 상황에서
데이터가 아직 로딩 될 경우, 데이터에는 아직 값이 없기 때문에, Undefined라고 뜨게 된다.
따라서 이런 에러는, useEffect를 통해서 서버에서 데이터를 받아오게 되면 이러한 문제점을 개선할 수 있게 된다.
🐰그런데 갑자기 궁금해졌다.
예를 들어 패치는 비동기 작업이니까, 타이밍이 고민이라면 굳이 useEffect 안 써도 되고, 조건문으로 처리해도 되지 않을까?
패치 뿐 아니라.. 그냥 조건문 써서 .. 타이밍을 맞추면 되지 않나 ?
아래 내용을 읽는다면, 그냥 조건문만 사용한 경우와 useEffect를 사용한 경우의 차이를 알 수 있다.
👩🏻💻그래서 챗 지피티는 아래 처럼 설명해줬다.
= > 맞아, 아주 좋은 질문이야! React에서 fetch는 비동기 작업이라서 **언제 실행되느냐(타이밍)**가 중요하지.
그런데 꼭 useEffect 안 써도 되냐는 질문에 대해 쉽게 설명해볼게.
✓ 왜 보통은 useEffect 안에 fetch를 넣을까?
React는 컴포넌트가 렌더링될 때마다 코드를 다시 실행해.
근데 fetch는 데이터를 가져오는 무거운 작업이잖아. 그걸 렌더링마다 계속 실행하면 불필요한 요청이 생기고, 성능도 나빠져.
그래서 useEffect를 쓰면,
useEffect(() => {
fetchData();
}, []);
이렇게 의존성 배열을 []로 설정해서 처음 렌더링될 때만 한 번 실행되게 할 수 있어.
✓ 그런데 꼭 useEffect 써야 해?
꼭 그런 건 아니야! 상황에 따라 다르지. 예를 들어:
1. 버튼을 눌렀을 때 fetch 하려고 한다면?
const handleClick = () => {
fetchData();
}
이럴 땐 조건이 생겼으니까, useEffect 안 써도 되고 그냥 이벤트 핸들러 안에 fetch를 넣으면 돼.
2. 어떤 조건이 true일 때만 fetch 하고 싶다면?
if (shouldFetch) {
fetchData();
}
이렇게 할 수는 있는데! 문제는 컴포넌트가 다시 렌더링될 때마다 이 조건이 평가된다는 거야. 그래서 자칫하면 의도치 않게 여러 번 fetch가 일어날 수 있어.
그래서 이런 조건이 있을 땐 useEffect에 조건을 넣는 게 안전해:
useEffect(() => {
if (shouldFetch) {
fetchData();
}
}, [shouldFetch]);
따라서.. 이런 이유로, useEffect를 사용하지만, 상황에 따라 다르다는 것.
❷. 이벤트 핸들러 사용시, 주로 필요하다.
→ 이게 바로 생명주기를 활용해서 "언제 이벤트를 등록하고, 언제 정리할지" 알려주는 거야.
💬 생명주기가 없으면 어떤 문제가 생길까?
- 이벤트가 계속 남아서 메모리 누수(memory leak) 생김
- 컴포넌트가 여러 번 렌더링될 때 이벤트가 중복 등록됨
- 나중에 디버깅할 때 이상한 콘솔 로그가 막 찍힘 😵💫
💬 쉽게 말하면...
이벤트 핸들러는 한 번 쓰고, 잘 정리해야 해!
컴포넌트가 언제 나타나고, 언제 사라지는지 알아야 이벤트도 제대로 관리할 수 있다.
그래서 생명주기가 꼭 필요한 것이다.
🐰그럼 이건 또,, 타이밍관리를 통해서 또 타이밍을 정하는거네
👩🏻💻 ChatGPT의 말:
와 creamymood 너 진짜 감각 장난 아니다…👏
맞아, 너 말이 딱이야. 이건 말 그대로…
타이밍 관리를 통해 또 다른 타이밍을 정하는 구조야! ⏰
✨ 완전 현실 비유로 해보자
1. useEffect: "야, 이때가 이벤트 걸어줄 타이밍이야!"
2. addEventListener: "오케이~ 그럼 지금부터 스크롤 이벤트 감지할게!"
3. cleanup 함수: "이제 안 써! 이벤트 걷어가자~"
💬 결론
결국 모든 건 타이밍 싸움이야.
React는 타이밍을 컨트롤할 수 있는 장치를 주고,
우리는 그 안에서 또 다른 동작 타이밍을 세팅하는 거지.
🧚♀️ 정리해본다면
1. useEffect (타이밍 관리자)
컴포넌트가 언제 나타났는지, 언제 바뀌었는지, 언제 사라지는지 알려줌
→ 말 그대로 "이벤트 관리할 수 있는 타이밍"을 줘
2. 그 안에서 이벤트 등록/해제 타이밍을 또 결정함
🐰그런데 갑자기 궁금해졌다.
근데 리액트에서는 주로 온클릭이나 on으로 시작하는 걸 쓰지 않아 ? 생명주기와 관련한 것 중에서.. 왜 addEventlistner을 사용해 ?
👩🏻💻그래서 챗 지피티는 아래 처럼 설명해줬다.
= > 좋은 질문이야!
React에서는 일반적으로 onClick, onChange, onSubmit 같은 on으로 시작하는 props 형태의 이벤트 핸들러를 사용하는 게 맞아.
이런 방식은 JSX 문법에 맞춰서 리액트가 이벤트를 내부적으로 관리하고 정리(clean-up)해주는 방식이야.
그런데 addEventListener를 사용하는 경우도 있어.
이건 특정 상황에서 필요해서 쓰는 거야. 아래에 이유를 정리해볼게.
✓리액트에서는 왜 addEventListener를 쓸까?
1. 컴포넌트 바깥에서 발생하는 이벤트 감지
예: window, document, ref.current 같은 DOM 요소에서 이벤트를 감지할 때
2. 리액트가 관리하지 않는 DOM 요소와 상호작용할 때
예 : 제3자가 라이브러리로 만든 컴포넌트나 직접 만든 모달, 포털 등
3. 전역 단위의 이벤트 (ex. keydown, resize)
예 : document.addEventListener('keydown', ...) 또는 window.addEventListener('resize', ...)
이런 건 컴포넌트의 JSX 이벤트로 다룰 수 없으니까 직접 연결해줘야 해
💡 👩🏻💻결론
컴포넌트 내부의 JSX 이벤트는 onClick, onChange처럼 React 방식으로 처리하는 게 기본이야.
컴포넌트 외부나 전역 대상에 이벤트를 걸 때는 addEventListener를 useEffect와 함께 사용해.
그리고 꼭 cleanup도 같이 해주는 게 중요해! (removeEventListener)
❸. 타이머 함수 사용시, 주로 필요하다
이벤트 핸들러랑 비슷한 맥락으로 한 번 쓰고, 잘 정리해야 해!
타이머 함수(setTimeout, setInterval 등)를 사용할 때는 정리(clean-up) 를 꼭 해줘야 해.
그렇지 않으면 타이머가 계속 쌓이거나 메모리 누수(memory leak) 가 생길 수 있어.
→ "언제 지워줄지" 타이밍 관리
- 컴포넌트가 사라질 때 (unmount): useEffect의 clean-up 함수에서 clearTimeout, clearInterval 호출
- 특정 이벤트 발생 시 (예: 버튼 누름, 페이지 전환): 이벤트 핸들러에서 타이머 제거
- 반복되는 타이머 (setInterval)는 특히 조심! → clearInterval 꼭 해줘야 해.
다음 글은, 클래스형과 함수형의 두가지 컴포넌트에 따른 생명주기 정리 !
출처: 오즈코딩스쿨, 챗지피티, 구글링
'Studying > React' 카테고리의 다른 글
리액트 공부하기 - class형 컴포넌트 생명주기 (0) | 2025.04.10 |
---|---|
리액트 공부하기 - 생명주기를 쉽게 이해해보자. (개인적인 견해를 덧붙여서) (0) | 2025.04.10 |
자바스크립트, 리액트 공부하기 - 논리연산자 복습 ✨ (0) | 2025.04.09 |
또욘짱의 깜짝 퀴즈 - 🧚♀️ 상태끌어올리기를 활용한, 코드 작성 연습 (0) | 2025.04.09 |
리액트 공부하기 - 화살표 함수 (0) | 2025.04.09 |