[React 🔯] 07. 라이프 사이클
![[React 🔯] 07. 라이프 사이클](/images/useBlog/react.jpg)
라이프사이클 (LifeCycle)
라이프사이클이란?

우리말로는 생애 주기를 뜻하는 단어이다. 생애 주기라는 것은 인간의 탄생부터 죽음까지의 타임라인을 단계별로 나누어 놓은 것을 말한다.
리액트 컴포넌트의 라이프사이클

Mount (탄생)
- 컴포넌트가 탄생하는 순간
- 화면에 처음 렌더링 되는 순간 A 컴포넌트가 Mount 되었다. => A 컴포넌트가 화면에 처음으로 렌더링 되었다.
Update (변화)
- 컴포넌트가 다시 렌더링 되는 순간
- 리렌더링 될 때를 의미 A 컴포넌트가 업데이트 되었다. => A 컴포넌트가 리렌더링 되었다.
UnMount (죽음)
- 컴포넌트가 화면에서 사라지는 순간
- 렌더링에서 제외되는 순간을 의미 A 컴포넌트가 언마운트 되었다. => A 컴포넌트가 화면에서 사라졌다.
컴포넌트의 라이프사이클을 잘 이해하고 있다면 우리가 원하는 타이밍에 컴포넌트에게 어떠한 작업을 실행시키도록 만들수 있다.

이렇게 컴포넌트의 라이프 사이클의 단계별로 우리 컴포넌트들이 각각 다른 작업을 수행하도록 만드는 것을 라이프 사이클 제어라고 부른다. useEffect를 이용하면 손쉽게 구현할 수 있다.
useEffect
useEffect란?
리액트 컴포넌트의 사이드 이펙트를 제어하는 새로운 React Hook이다.
사이트 이펙트? 우리말로는 부작용이라는 뜻이다. 리액트에서는 "부수적인 효과", "파생되는 효과"정도로 해석 가능하다.

useEffect 실습해보기
지난시간 만들었던 Simple Counter App을 사용하여 실습할 예정이다. 👉🏻 지난시간 Simple Counter App
import { useState, useEffect } from 'react';
useEffect(() => {
console.log(`count: ${count}`);
}, [count]);
첫 번째 인수로는 콜백함수를, 두 번째 인수로 배열을 넣는다. 이렇게 하면 useEffect는 두 번째 인수로 전달한 이 배열에 들어가 있는 'count' State 값이 바뀌게 되면 SidEffect로서 첫 번째 인수로 전달한 이 콜백 함수 console.log('count: ${count}');를 실행시킨다.

useEffect라는 훅은 두 번째 인수로 전달한 배열에 의존한다. 이 배열에다가 무엇을 넣느냐에 따라서 다르게 동작하기 때문에 이 배열을 **의존성 배열 (dependency array -> 줄여서 deps)**라고 부른다. deps에는 값을 여러 개 넣어도 된다.
import {useState, useEffect} from "react";
function App() {
const [input, setInput] = useState("");
useEffect(() => {
console.log(`count: ${count} / input: ${input}`);
}, [count, input]);
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input
value={input}
onChange={(e) => {
setInput(e.target.value);
}}
/>
</section>
input이 바뀔 때에도 출력이 된다.

useEffect를 이용하여 컴퍼넌트에 라이프사이클 제어하기
1. Mount를 useEffect로 제어하기
useEffect(() => {
console.log('mount');
}, []);
콘솔에 mount 메시지가 최초로 출력이 되는데 그 이후에는 아무리 state 값을 변경한다고 하더라고 다시는 이 메시지가 출력되지 않는다.
컴포넌트가 마운트 되었을 때만 딱 최초로 한 번 실행시키고 싶은 코드가 있다는 useEffect를 호출하고 deps로는 빈 배열을 전달해 주면 된다.

2. Update를 useEffect로 제어하기
useEffect(() => {
console.log('update');
});
mount와 똑같이 useEffect를 호출하고 두 번쨰 인수인 배열을 생략해주면 된다.
이러면 최초로 실행했을때 mount, update가 출력이 되고 state 값이 변화하여 리렌더링 될 때마다 update가 계속 출력된다.

마운트 시점을 제외하고 컴포넌트가 마운트 되고 나서 업데이트가 되는 순간에만 실행 시키는 방법
useRef를 이용하여 변수 생성
import { useState, useRef, useEffect } from 'react';
function App() {
const isMount = useRef(false);
useEffect(() => {
if (!isMount.current) {
isMount.current = true;
return;
}
console.log('update');
});
}
useEffect는 기본적으로 컴포넌트가 처음 마운트될 때도 실행된다. 마운트 시점을 건너뛰고 업데이트될 때만 실행하고 싶다면 useRef로 마운트 여부를 추적하는 변수를 만들면 된다.
isMount의 초기값은 false다. useEffect가 처음 실행되는 마운트 시점에는 isMount.current가 false이므로 if (!isMount.current) 조건이 참이 되어 isMount.current = true로 바꾸고 return으로 빠져나온다. 즉 마운트 시점에는 아무것도 실행하지 않는다.
이후 State가 변경되어 업데이트가 발생하면 useEffect가 다시 실행되는데, 이때는 isMount.current가 이미 true이므로 if 조건을 통과하지 못하고 console.log("update")가 실행된다.


UnMount를 useEffect로 제어하기
화면에 나타났다가 사라졌다가 하는 컴포넌트가 추가로 필요하기 때문에 컴포넌트를 하나 생성해야 한다.
Even.jsx
// src/components/Even.jsx
import { useEffect } from 'react';
const Even = () => {
useEffect(() => {
return () => {
console.log('unmount');
};
}, []);
return <div>짝수입니다.</div>;
};
export default Even;
// src/App.jsx
import Even from './components/Even';
<section>
<Viewer count={count} />
{count % 2 === 0 ? <Even /> : null}
</section>;
useEffect의 콜백 함수 안에서 함수를 return하면 그 함수가 클린업(Cleanup) 함수가 된다. 클린업 함수는 컴포넌트가 화면에서 사라지는 언마운트 시점에 실행된다.
useEffect의 두 번째 인수로 빈 배열 []을 전달했기 때문에 이 effect는 마운트 시점에 딱 한 번만 등록되고, 이후 업데이트 시에는 다시 실행되지 않는다. 언마운트될 때 return한 클린업 함수만 실행되어 console.log("unmount")가 출력된다.
App.jsx에서 count % 2 === 0 ? <Even /> : null은 count가 짝수일 때만 Even 컴포넌트를 렌더링하고, 홀수가 되면 null을 반환해 화면에서 제거한다. 짝수 → 홀수가 되는 순간 Even 컴포넌트가 언마운트되면서 클린업 함수가 실행된다.




React 개발자 도구 사용하기
[👉🏻 크롬 확장 프로그램 설치 - React Developer Tools] (https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?utm_source=ext_app_menu)

링크에서 설치하면 크롬 확장 프로그램 목록에 React Developer Tools가 추가된다. 우측 토글이 켜져 있는지 확인해서 활성화 상태인지 체크하자. 활성화 되어있는지 확인하기!!

세부정보 페이지에서 사용 토글이 켜져 있는지, 파일 URL에 대한 액세스 허용이 활성화되어 있는지 확인한다. 로컬 환경(localhost)에서 개발할 때도 정상적으로 동작하려면 파일 URL 액세스 허용이 켜져 있어야 한다.


React 앱을 실행하면 상단에 development build 안내 메시지가 뜨는데, 개발자 도구를 열면 Components 탭이 새로 생긴 것을 확인할 수 있다. Console 탭에서는 useEffect로 찍은 mount 로그가 출력되고, Components 탭에서는 App > Viewer, Even, Controller 계층 구조와 함께 현재 hooks 상태(State: 0, Ref: true, Effect 등)를 실시간으로 확인할 수 있다.

Components 탭 우측 상단 설정 아이콘을 클릭하면 General 설정 팝업이 열린다. 여기서 Highlight updates when components render 옵션을 체크하면 State나 Props가 변경되어 리렌더링이 발생할 때 해당 컴포넌트에 노란 테두리가 표시된다. 어떤 컴포넌트가 얼마나 자주 리렌더링되는지 시각적으로 확인할 수 있어 불필요한 리렌더링을 찾아내는 데 유용하다.
