Language/React.js
[React] 라이프 사이클
JJcoding
2024. 10. 17. 15:53
Mount
- 탄생. 컴포넌트가 탄생하는 순간
- 화면에 처음 렌더링 되는 순간
- “A 컴포넌트가 Mount 되었다.” = A 컴포넌트가 화면에 렌더링 되었다.
- 서버에서 데이터를 불러오는 작업 등을 할 수 있다.
Update
- 변화. 컴포넌트가 다시 렌더링 되는 순간
- 리렌더링 될 때를 의미
- “A 컴포넌트가 업데이트 되었다.” = A 컴포넌트가 리렌더링 되었다.
- 어떤 값이 변경되었는지 콘솔에 출력 등을 할 수 있다.
UnMount
- 죽음. 컴포넌트가 화면에서 사라지는 순간
- 렌더링에서 제외되는 순간을 의미
- “A 컴포넌트가 언마운트 되었다.” = A 컴포넌트가 화면에서 사라졌다.
- 컴포넌트가 사용하던 메모리 정리 등을 할 수 있다.
- 라이프사이클 단계 별로 컴포넌트들이 각각 다른 작업을 수행하도록 만드는 것을 라이프사이클 제어라고 한다.
useEffect
- 리액트 컴포넌트의 사이드 이펙트를 제어하는 새로운 React Hook
- 사이드 이펙트 : 리액트에서는 부수적인 효과, 파생되는 효과로 해석하면 된다.
App.jsx
import "./App.css";
import { useState, useEffect } from "react";
import Viewer from "./components/Viewer";
import Controller from "./components/Controller";
function App() {
const [count, setCount] = useState(0);
const [input, setInput] = useState("");
**useEffect(() => {
console.log(`count: ${count} / input: ${input}`);
}, [count, input]);
// 의존성 배열
// dependency array => 줄여서 deps**
const onClickButton = (value) => {
setCount(count + value);
};
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input
value={input}
onChange={(e) => {
setInput(e.target.value);
}}
/>
</section>
<section>
<Viewer count={count} />
</section>
<section>
<Controller onClickButton={onClickButton} />
</section>
</div>
);
}
export default App;
- 배열(deps) 안에 들어있는 값이 변하면, 앞에 콜백 함수가 호출되는 방식이다.
- 그렇다면 onClickButton 함수가 실행될 때 console.log를 찍으면 똑같이 동작하는 것이 아닌가?
const onClickButton = (value) => {
setCount(count + value);
console.log(count);
};
- 결과는 아니다. 왜냐하면 state는 비동기 방식으로 동작하기 때문이다. 따라서 콘솔에 나온 결과값은 함수가 실행되기 전에 값으로 출력이 된다.
- 따라서 state가 변경되었을 때 어떤 변화를 살펴보고 싶다면 useEffect 훅을 사용해야 한다.
useEffect로 라이프사이클 제어하기
App.jsx
import "./App.css";
import { useState, useEffect, useRef } from "react";
import Viewer from "./components/Viewer";
import Controller from "./components/Controller";
import Even from "./components/Even";
function App() {
const [count, setCount] = useState(0);
const [input, setInput] = useState("");
const isMount = useRef(false);
// 1. 마운트 : 탄생
useEffect(() => {
console.log("mount");
}, []);
// 2. 업데이트 : 변화, 리렌더링
useEffect(() => {
if (!isMount.current) {
isMount.current = true;
return;
}
console.log("update");
});
//3. 언마운트 : 죽음
const onClickButton = (value) => {
setCount(count + value);
};
return (
<div className="App">
<h1>Simple Counter</h1>
<section>
<input
value={input}
onChange={(e) => {
setInput(e.target.value);
}}
/>
</section>
<section>
<Viewer count={count} />
{count % 2 === 0 ? <Even /> : null}
</section>
<section>
<Controller onClickButton={onClickButton} />
</section>
</div>
);
}
export default App;
- deps에 빈 배열을 넣으면 mount 될 때만 useEffect 함수가 실행된다.
- deps에 아무것도 넣지 않으면 mount 될 때, update 될 때 모두 useEffect 함수가 실행된다.
- 만약 update가 될 때만 함수가 실행되게 하고 싶다면 위처럼 useRef 함수를 활용할 수 있다.
- unmount 실습을 위해 나타났다 사라졌다 하는 컴포넌트를 생성한다.
Even.jsx
import { useEffect } from "react";
const Even = () => {
useEffect(() => {
// 클린업, 정리함수
return () => {
console.log("unmount");
};
}, []);
return <div>짝수입니다.</div>;
};
export default Even;
- 정리함수(useEffect 안에 있는 return 함수)는 useEffect가 끝날 때 실행이 된다.
출처 : 한입 크기로 잘라먹는 리액트