React의 내장 Hook 중 하나로, 컴포넌트가 렌더링된 이후에 비동기 작업을 수행하기 위해 사용
데이터 fetching, subscription, 또는 수동으로 React 컴포넌트의 DOM을 변경해야 하는 경우에 쓰임
데이터를 가져오거나, 이벤트 리스너를 설정, 타이머 설정 등의 side effect를 처리
side effect를 그룹화하여 코드를 분리하고 관리할 수 있음, 코드의 가독성을 높이고 각 side effect의 독립성을 유지할 수 있음.
function ExampleComponent() {
// API 호출 useEffect
useEffect(() => {
fetchData();
}, []);
// 이벤트 리스너 설정 useEffect
useEffect(() => {
window.addEventListener('resize', handleResize);
// 컴포넌트 언마운트 또는 재실행 전에 이벤트 리스너 제거
return () => window.removeEventListener('resize', handleResize);
}, []);
// ...
}
import React, { useEffect } from 'react';
useEffect(() => {
// 컴포넌트가 렌더링된 후에 실행될 코드를 여기에 작성합니다.
}, [/* 의존성 배열 */]);
useEffect
안의 함수는 컴포넌트가 렌더링 될 때마다 렌더링 이후에 실행useEffect(() => {
console.log('렌더링 시 출력');
});
useEffect
안의 함수는 컴포넌트가 처음 마운트(DOM 객체가 생성되고 브라우저에 나타나는 것) 될 때만 실행useEffect(() => {
console.log('처음 렌더링 시에만 출력');
}, []);
useEffect
안의 함수는 컴포넌트가 처음 마운트 될 때, 그리고 배열에 명시된 값들이 변경될 때마다 실행const [count, setCount] = useState(0);
useEffect(() => {
console.log('count의 값이 변할 때마다 출력');
}, [count]);
return (
<>
<h1>{count}</h1>
<button onClick={() => setCount(count+1)}>클릭</button>
</>
)
useEffect
가 다시 실행 되기 때문에, 의존성 배열을 빼놓거나 잘못 관리하면 예상치 못한 버그를 유발할 수 있음.const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
// 의존성 배열에서 'count'를 빠뜨림
}, []);
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
// 'count'를 의존성 배열에 포함
}, [count]);
const [count, setCount] = useState(0);
const [name, setName] = useState('John');
useEffect(() => {
document.title = `${name} clicked ${count} times`;
// 'count'와 'name' 모두 의존성 배열에 포함
}, [count, name]);
useEffect
내부에서 반환하는 함수
컴포넌트가 언마운트 (DOM에서 제거되는 과정)되거나, useEffect
가 재실행되기 전에 호출
이 함수를 사용해 이벤트 리스너를 제거하거나, 타이머를 정리하는 등의 작업을 수행해야 함
정리 함수를 빼놓으면 메모리 누수 등의 문제를 유발할 수 있음
// App.js
function App() {
const [show, setShow] = useState(true);
return (
<div>
{show && <Timer />}
<button onClick={() => setShow(!show)}>Toggle Timer</button>
</div>
);
}
// Timer.js
const Timer = () => {
useEffect(() => {
// 컴포넌트가 마운트 되었을 때 실행
const timer = setInterval(() => {
console.log('타이머 시작');
}, 1000);
return () => {
// 컴포넌트가 언마운트될 때 실행
clearInterval(timer);
console.log('타이머 종료');
}
}, []);
return (
<div>
<span>타이머를 시작합니다.</span>
</div>
)
}
useEffect
내에서 비동기 함수를 직접 호출하면 경고가 발생
useEffect
내부에서 새로운 함수를 선언하고 그 함수 안에서 비동기 작업을 수행해야 함
useEffect
는 정리 함수를 반환해야 하는데, 비동기 함수는 항상 Promise를 반환하기 때문에 React는 useEffect 함수에서 Promise를 반환하게 하지 않도록 경고를 띄움
useEffect(async () => {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
}, []); // 의존성 배열
useEffect(() => {
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
}
fetchData();
}, []); // 의존성 배열
const [data, setData] = useState(null);
useEffect(() => {
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
setData(data);
}
fetchData();
}, []); // 의존성 배열