[React] useEffect
[ 개념 ]
어떠한 컴포넌트가 마운트 되었을 떄, 업데이트 될 때, 언마운트 되었을 때
특정 작업을 처리 할 코드를 실행할 때 useEffect를 사용합니다.
기본적으로 useEffect Hook은 인자로 콜백 함수를 받습니다.
(콜백 함수란? 다른 함수의 인자로 전달된 함수를 말합니다.)
useEffect는 아래와 같이 두가지 형태만 알고 있으면 됩니다.
첫번째 형태는 useEffect의 인자로 하나의 콜백 함수만 받는 형태이고
두번째 형태는 useEffect의 첫번째 인자로 콜백 함수, 두번째 인자로는 배열(dependency array)를 받는 형태 입니다.
첫번째 형태를 사용할 경우 컴포넌트가 렌더링 될 때마다 콜백 함수가 실행 됩니다.
두번째 형태는 매번 렌더링 될 때마다 실행 되는 것이 아니라
컴포넌트가 첫 렌더링 될 때 + dependency array에 넣어준 value의 값이 바뀔 때 실행 됩니다.
두번째 인자(dependency array)가 빈 배열일 경우 컴포넌트가 첫 렌더링 될 때만 실행 됩니다.
추가적으로 Clean Up 함수가 있습니다.
Clean Up 함수는 useEffect 콜백 함수 안에서 어떤 서비스에 구독하는 코드를 넣었다면
컴포넌트가 사라질 때(언마운트 될 때) 구독을 해제 해주는 코드를 넣어야 합니다.
(예를 들어 setTimeout/setInterval을 실행 했다면 Clean Up 함수에서
cleatTimeOut/clearInterval을 추가적으로 작업 해줘야 합니다.)
Clean Up === 정리 작업
[ 실습 ]
매번 렌더링 될 때마다 실행하는 예제
import React, { useState, useEffect } from "react";
import "./App.css";
function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState("");
const handleCountUpdate = () => {
setCount(count + 1);
};
const handleInputChange = (e) => {
setName(e.target.value);
};
// 렌더링 될 때마다 매번 실행됨
useEffect(() => {
console.log("렌더링");
});
return (
<div>
<button onClick={handleCountUpdate}>Update</button>
<span>count : {count}</span>
<br />
<input type="text" value={name} onChange={handleInputChange}></input>
<br />
<span>{name}</span>
</div>
);
}
export default App;
count state의 값이 바뀔 때마다 실행되는 예제
.. 생략
// 마운트 + [item] 변경 시에만 실행
useEffect(() => {
console.log("렌더링");
}, [count]);
.. 생략
첫 마운트 때만 실행되는 예제
.. 생략
// 첫 마운트 때만 실행
useEffect(() => {
console.log("렌더링");
}, []);
.. 생략
Clean Up 예제
// Timer.js
import React, { useEffect } from "react";
const Timer = () => {
// 렌더링 될 때마다 매번 실행됨
useEffect((props) => {
const timer = setInterval(() => {
console.log("타이머 돌아가는 중");
}, 1000);
}, []);
return (
<div>
<span>타이머가 시작됩니다. 콘솔을 보세요!</span>
</div>
);
};
export default Timer;
// App.js
import React, { useState } from "react";
import Timer from "./Timer";
import "./App.css";
function App() {
const [showTimer, setShowTimer] = useState(false);
return (
<div>
{showTimer && <Timer />}
<button
onClick={() => {
setShowTimer(!showTimer);
}}
>
Toggle Timer
</button>
</div>
);
}
export default App;
Clean Up을 안해줄 경우 타이머를 멈춰도 멈추지 않는다!!!
Clean Up을 사용하여 정리 해줄 경우
// Timer.js
import React, { useEffect } from "react";
const Timer = () => {
// 렌더링 될 때마다 매번 실행됨
useEffect((props) => {
const timer = setInterval(() => {
console.log("타이머 돌아가는 중");
}, 1000);
return () => {
clearInterval(timer);
console.log("타이머 종료")
}
}, []);
return (
<div>
<span>타이머가 시작됩니다. 콘솔을 보세요!</span>
</div>
);
};
export default Timer;
잘 종료 된 것 볼 수 있다.