
1. 리액트 컴포넌트와 라이프 사이클
리액트 컴포넌트 = 라이프 사이

Mount: 컴포넌트를 페이지에 처음 렌더링 할 때
Update: State나 Props의 값이 바뀌거나 부모 컴포넌트가 리렌더해 지신도 리렌더 될때
Unmount: 더 이상 페이지에 컴포넌트를 렌더링하지 않을 때
라이프 사이클을 이용하면 컴포넌트가 처음 렌더링할 때 특정 동작을 하도록 만들거나, 업데이트힐 때 적정한지 검사하거나, 페이지에서 사라질 때 메모리를 정리하는 등 여러 유용한 작업을 할 수 있다. 이를 라이프 사이클 제어라고 하며, 리액트 훅의 하나인 uesEffect를 이용하여 제어할 수 있다.
2. useEffect
useEffect: 값이 변결할 때마다 특정 코드를 실행하는 리액트의 훅 ("특정 값을 검사한다.")
useEffect를 사용하면 컴포넌트의 State값이 바뀔 때마다 변경된 값을 콘솔에 출력할 수 있습니다.
1. 하나의 값 검사하기
App컴포넌트에서 State변수 count의 값이 바뀌면, 변경된 값을 콘솔에 출력하겠습니다.
useEffect의 용법
2useEffect(callback, [deps])
3 콜백 함수 의존성 배열
두번째 인수로 전달되는 의존성 배열의 요소값이 변경되면 첫 번째 인수로 전달한 콜백함수를 실행합니다.
import "./App.css";
import { useState, useEffect } from "react";
import Controller from "./component/Controller";
import Viewer from "./component/Viewer";
function App() {
const [count, setCount] = useState(0);
const handleSetCount = (value) => {
setCount(count + value);
};
useEffect(() => { // useEffect를 호출하고 두 개의 인수를 전달합니다. 첫 번째 인수로 콜백 함수를, 두 번째 인수로 배열을 전달
console.log("count 업데이트: ", count);
}, [count]);
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
</div>
);
}
export default App;
코드에서 의존성 배열요소에 State변수 count가 있어서 이 값이 바뀌면 callback함수가 실행됩니다. 이 함수는 "count 업데이트"라는 문자열과 함께 State값을 출력합니다.
이때 "count 업데이트: 0"이 콘솔에 출력되는데, State값을 초기화 할 때도 useEffect가 이 변화를 감지하기 때문입니다.

useEffect를 이용하면 특정 값이 바뀔 때마다 원한는 코드를 실행하도록 만들 수 있습니다.
2. 여러 개의 값 검사하기
배열요소가 여러개 있으면 요소 중 하나가 변경되면 useEffect는 콜백함수를 실행합니다.
State변수 count외에 임ㅁ수 입력폼 추가하고, text라는 State변수를 하나 더 만들겠습니다.
//src/App.js
import "./App.css";
import { useState, useEffect } from "react";
import Controller from "./component/Controller";
import Viewer from "./component/Viewer";
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState(""); // State변수 text만들기
b
const handleSetCount = (value) => {
setCount(count + value);
};
const handleChangeText = (e) => { // onChange 이벤트 핸들러 함수 만들기
setText(e.target.value);
};b
useEffect(() => {
console.log("업데이트: ", text, count);
}, [count, text]);
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input value={text} onChange={handleChangeText} />
</section>b
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
</div>
);
}
export default App;

3. useEffect로 라이프 사이클 제어하기
useEffec의 마운트 시점말고 Update시점에서만 콜백함수를 실행하겠습니다.
즉, 페이지에 처음 렌더링할 떄는 콜백함수를 실행하지 않고 리렌더될 때만 실행하겠다는 뜻입니다.
import "./App.css";
import { useRef, useState, useEffect } from "react";
import Controller from "./component/Controller";
import Viewer from "./component/Viewer";
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const didMountRef = useRef(false); // 페이지에 마운트했는지 판단하는 변수 didMountRef
const handleSetCount = (value) => {
setCount(count + value);
};
const handleChangeText = (e) => {
setText(e.target.value);
};
useEffect(() => { // 의존성 배열로 아무것도 전달하지 않았으므로, 콜백 함수는 마운트 시점에도 실행되어야 합니다.
if (!didMountRef.current) { // 마운트 시점에는 콘솔에 ‘컴포넌트 업데이트’ 문자열을 출력하지 않도록
didMountRef.current = true;
return;
} else {
console.log("컴포넌트 업데이트!");
}
});
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input value={text} onChange={handleChangeText} />
</section>
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
</div>
);
}
export default App;

4. 컴포넌트의 마운트 제어하기
컴포넌트 마운트 시점에서 "컴포넌트의 마운트를 제어한다."
import "./App.css";
import { useRef, useState, useEffect } from "react";
import Controller from "./component/Controller";
import Viewer from "./component/Viewer";
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const didMountRef = useRef(false);
const handleSetCount = (value) => {
setCount(count + value);
};
const handleChangeText = (e) => {
setText(e.target.value);
};
useEffect(() => {
if (!didMountRef.current) {
didMountRef.current = true;
return;
} else {
console.log("컴포넌트 업데이트!");
}
});
useEffect(() => {
console.log("컴포넌트 마운트");
}, []);
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input value={text} onChange={handleChangeText} />
</section>
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
</div>
);
}
export default App;

5. 컴포넌트 언마운트 제어하기
언마운트: 컴포넌트가 페이지에서 제거될 때
(1) 클린업
컴포넌트가 제거되기 위해서는 클린업 기능을 수행해야한다.
클린업: 특정 함수가 실행되고 종요된 후에, 미처 정리하지 못한 사항을 처리하는 일
import "./App.css";
import { useRef, useState, useEffect } from "react";
import Controller from "./component/Controller";
import Viewer from "./component/Viewer";
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const didMountRef = useRef(false);
const handleSetCount = (value) => {
setCount(count + value);
};
const handleChangeText = (e) => {
setText(e.target.value);
};
useEffect(() => {
if (!didMountRef.current) {
didMountRef.current = true;
return;
} else {
console.log("컴포넌트 업데이트!");
}
});
useEffect(() => { // 의존성 배열은 전달x
const intervalID = setInterval(() => { // // 콜백 함수는 다시 함수 setInterval을 호출 -> 인터벌(Interval, 시간 간격)을 설정하는 함수입니다. 결과적으로 1초마다 콘솔에 문자열 깜빡 을 출력합니다.
console.log("깜빡");
}, 1000);
return () => { // 컴포넌트가 언마운트하는 시점에 실행
console.log("클린업");
clearInterval(intervalID); // 클린업 함수는 clearInterval을 호출
};
});
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input value={text} onChange={handleChangeText} />
</section>
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
</div>
);
}
export default App;

정리하면 useEffect의 콜백 함수가 반환하는 함수를 클린업 함수라고 합니다. 이 함수는 콜백 함수를 다시 호출하기 전에 실행됩니다. 따라서 컴포넌트를 렌더링할 때 마다 새 인터벌을 생성하고 기존 인터벌은 삭제합니다.
(2) 클린업을 이용해 컴포넌트 언마운트 제어하기
컴포넌트가 페이지에서 사라질 대 원하는 코드를 실행하는 "컴포넌트 언마운트"
컴포넌트는 count값이 짝수면 특정 문자열을 페이지에 렌더링하는 조건부 렌더링 구현.
// src/component/Even.js
import { useEffect } from "react";
function Even() {
useEffect(() => {
return () => {
console.log("Even 컴포넌트 언마운트");
};
}, []);
return <div>현재 카운트는 짝수입니다</div>;
}
export default Even;
import "./App.css";
import { useRef, useState, useEffect } from "react";
import Controller from "./component/Controller";
import Viewer from "./component/Viewer";
import Even from "./component/Event";
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");
const didMountRef = useRef(false);
const handleSetCount = (value) => {
setCount(count + value);
};
const handleChangeText = (e) => {
setText(e.target.value);
};
useEffect(() => {
if (!didMountRef.current) {
didMountRef.current = true;
return;
} else {
console.log("컴포넌트 업데이트!");
}
});
useEffect(() => {
console.log("컴포넌트 마운트");
}, []);
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input value={text} onChange={handleChangeText} />
</section>
<section>
<Viewer count={count} />
</section>
<section>
<Controller handleSetCount={handleSetCount} />
</section>
<section>
<Viewer count={count} />
{count % 2 === 0 && <Even />}
</section>
</div>
);
}
export default App;

3. 리액트 개발자 도구
State 값이 변경될 때마다 useEffect 를 수정하고 console.log로 확인한다면 이는 무척 번거로운 일이 될 겁니다.
따라서 이번 절에서는 리액트 앱을 개발할 때 매우 유용하게 사용하는 리액트 개발자 도구(React Developer Tools)를 소개하려 합니다.
1. 리액트 개발자 도구 설치하기
크롬 브라우저 확장 프로그램
[chrome 웹스토어]: https://chromewebstore.google.com/category/extensions?pli=1
Chrome Web Store
브라우저에 새로운 기능을 추가하고 탐색 환경을 맞춤설정합니다.
chromewebstore.google.com
[확장 프로그램 검색] -> 'React Developer Tools'입력 후 엔터 -> [ React Developer Tools] 클릭 -> [크롭에 추가]

[확장 프로그램] 페이지 가져오기

[세부정보] 페이지 가져오기


React Developer Tools의 핀을 고정

2. 설치확인하기
비주얼 스튜디오: npm run start

전 크롭 연동이 안되어 있어서 마이크로 엣지에 따로 확장을 설치했습니다.
3. 리액트 개발자 도구의 기능 사용하기
(1) 컴포넌트 트리 살펴보기
[개발자 도구] -> [components탭]

App.js루트를 통해 그 아래에 Viewer, Even, Controller 3개의 자식 컴포넌트 확인 가능
(2) State모니터링하기
[components탭]에서 실시간으로 State값 모니터링 하기

앱 페이지에서 버튼을 눌러 현재 카운트를 계속해서 바꾸는지 확인합니다.
(3) Props모니터링 하기
[components탭]에서 Viewer컨포넌트를 클릭 ->
Viewer은 App컨포넌트가 전당한 count를 props로 받아 페이지에 렌더링

(4) 리렌더 하이라이트 기능 사용하기: 의미 없이 리렌더되는지 확인가능.
[components탭]에서 -> 톱니바퀴 -> View settings -> [General] 탭 -> “Highlight updates when component render.”라고 쓰여 있는 체크박스에 표시


출처 : 이정환, 『한 입 크기로 잘라먹는 리액트』, 프로그래밍인사이트(2023).
'DEVELOPMENT > react' 카테고리의 다른 글
| 10. 할일 관리 앱 만들기 (0) | 2024.12.30 |
|---|---|
| 9. 리액트를 다루는 기술 - hooks (0) | 2024.12.23 |
| 7. 카운터 앱만들기 (0) | 2024.11.11 |
| 6. 리액트 기본 개념 다루기 - 2 (0) | 2024.11.10 |
| 5. 리액트 기본 개념 다루기 - 1 (0) | 2024.11.03 |