useEffect
는 컴포넌트가 Mounting(생성 될 때), Unmounting(제거 할 때), Updating(props나 state가 바뀔 때 등) 특정 작업(구독 설정, API 호출, 컴포넌트의 DOM 수정 등) 처리하는 함수이다.
useEffect
는 첫 번째 인자로 작업을 해야할 코드가 담긴 콜백 함수를 받고, 두 번째 인자(option)로는 Dependency Array(이하 의존성 배열)를 받는다.
만약에 빈 배열을 넣는다면 deps가 없어 변경되는 것이 없으므로 마운트 될 때 처음 한 번만 실행이 되고,
의존성 배열을 인자로 넣지 않는다면 컴포넌트가 렌더링 될 때마다 useEffect
에 등록된 콜백이 실행된다.
//1. 렌더링 될 때마다 실행
useEffect(() => { //작업...});
// 1. 마운트 될 때 실행
// 2. 배열 안의 value값이 바뀔 때 실행.
useEffect(() => { //작업...}, [value]);
아래의 코드를 그대로 가져가 버튼을 눌러보고 input태그에 타이핑을 해가며 마운트 / 언마운트 / 업데이트 타이밍을 알아보자.
import { useEffect, useState } from 'react';
function App() {
const [count, setCount] = useState(1);
const [name, setName] = useState('');
const countUpdateHandler = () => {
setCount(count + 1);
};
const inputChangeHandler = (e) => {
setName(e.target.value);
};
useEffect(() => {
console.log('렌더링 될 때 마다 실행');
});
useEffect(() => {
console.log('마운트 될 때 처음 한 번만 실행');
}, []);
// 마운트 + 업데이트
useEffect(() => {
console.log('마운트 될 때 처음 한 번만 실행 || count state가 변할 때 마다 실행');
}, [count]);
// 마운트 + 업데이트
useEffect(() => {
console.log('마운트 될 때 처음 한 번만 실행 || name state가 변할 때 마다 실행');
}, [name]);
return (
<div>
<button onClick={countUpdateHandler}>Update</button>
<span>count: {count}</span>
<div>
<input type="text" onChange={inputChangeHandler} />
<span>name: {name}</span>
</div>
</div>
);
}
export default App;
render는 DOM생성을 위해 함수가 호출 될 때.
컴포넌트의 인스턴스가 생성되어 DOM 상에 삽입이 될 때.
컴포넌트가 render될 때 mount 과정을 거친다.
그러나 props나 state가 변경되어 render 될 때는 mount를 거치지 않는다. 결국 mount는 DOM이 생성되고, 웹 브라우저상에 처음으로 나타나는 과정을 말하는 것이다.
위에서 useEffect는 컴포넌트 렌더링 이후 특정 작업 처리하는 함수라고 설명했다. 위의 실습 코드는 정리(Clean-up)가 필요하지 않은 코드였지만 useEffect를 사용하다 보면 정리(Clean-up)가 필요한 effect가 있다.(구독 설정, API 호출, 컴포넌트의 DOM 수정 등)
리액트는 컴포넌트가 마운트 해제되는 때에 정리(Clean-up)를 실행한다.
// App.js
import { useState } from 'react';
import FactriotRocket from './components/FactriotRocket';
function App() {
const [showTimer, setShowTimer] = useState(false);
const timerStatusHandler = () => {
setShowTimer(!showTimer);
};
return (
<div>
{showTimer && <FactriotRocket />}
<button onClick={timerStatusHandler}>
못생긴 남자가 은근히 인기 많은 이유
</button>
</div>
);
}
export default App;
// FactriotRocket.js
import { useEffect } from 'react';
const FactriotRocket = (props) => {
useEffect(() => {
const Patriot = setInterval(() => {
console.log('같은건 없습니다.');
}, 1000);
return () => {
clearInterval(Patriot);
console.log('그럼 전 20000');
};
}, []);
return (
<div>
<span>개발자 도구를 열어 콘솔을 보세요!</span>
</div>
);
};
export default FactriotRocket;