화면이 그려진 다음에 할 일
useEffect를 이해하고, 화면 렌더링 이후에 실행되는 코드를 다루는 방법을 배웁니다.
렌더링만으로는 부족할 때
지금까지 배운 흐름은 이랬습니다.
상태가 바뀌면 React가 화면을 다시 그린다.
그런데 실무에서는 "화면을 그린 다음에 해야 하는 일"이 있습니다.
- 화면이 뜨자마자 서버에서 데이터를 가져와야 한다
- 타이머를 걸어야 한다
- 외부 라이브러리를 초기화해야 한다
이런 일들은 화면을 그리는 것과는 별개입니다.
React에서는 이걸 부수 효과(side effect) 라고 부르고, useEffect로 다룹니다.
useEffect 기본 형태
useEffect(() => {
// 화면이 그려진 다음에 실행되는 코드
}, []);두 부분으로 나뉩니다.
- 첫 번째 인자: 실행할 함수
- 두 번째 인자: 의존성 배열 — 이 배열에 담긴 값이 바뀔 때마다 함수가 다시 실행됩니다
빈 배열 []을 넘기면 컴포넌트가 처음 화면에 나타날 때 딱 한 번 실행됩니다.
화면에 뜨자마자 데이터 가져오기
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(data => setUsers(data));
}, []);
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}흐름을 따라가면 이렇습니다.
- 컴포넌트가 화면에 나타남 (빈 목록)
useEffect실행 → 서버에 데이터 요청- 데이터 도착 →
setUsers로 상태 변경 - 상태가 바뀌었으니 화면 다시 그림 (목록 표시)
의존성 배열이 하는 일
의존성 배열에 값을 넣으면, 그 값이 바뀔 때마다 함수가 다시 실행됩니다.
const [userId, setUserId] = useState(1);
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => setUser(data));
}, [userId]);userId가 1에서 2로 바뀌면 useEffect 안의 함수가 다시 실행됩니다.
userId가 그대로면 실행하지 않습니다.
| 의존성 배열 | 실행 시점 |
|---|---|
[] | 처음 한 번만 |
[userId] | userId가 바뀔 때마다 |
| 생략 | 매 렌더링마다 (주의 필요) |
의존성 배열을 아예 생략하면 렌더링할 때마다 실행되기 때문에,
의도하지 않은 반복 실행이 발생할 수 있습니다. 대부분의 경우 배열을 명시하는 게 안전합니다.
정리 작업이 필요할 때
타이머나 이벤트 리스너처럼 "시작했으면 끝내야 하는" 작업은 정리 함수를 반환합니다.
useEffect(() => {
const timer = setInterval(() => {
console.log('tick');
}, 1000);
return () => {
clearInterval(timer);
};
}, []);return 으로 반환한 함수는 컴포넌트가 화면에서 사라질 때 실행됩니다.
정리를 안 하면 타이머가 계속 돌거나, 이벤트 리스너가 쌓이는 문제가 생깁니다.
시작한 건 반드시 끝내야 합니다.
흔한 실수
// 의존성 배열 없이 setState → 무한 루프
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(data => setUsers(data));
});의존성 배열을 생략하면 매 렌더링마다 실행됩니다.
setUsers → 렌더링 → useEffect 실행 → setUsers → 렌더링 → ...
끝없이 반복됩니다.
데이터 요청 같은 작업은 반드시 [] 또는 적절한 의존성 배열을 넣어주세요.
정리
useEffect는 화면이 그려진 다음에 실행되는 코드를 담는 곳이다.- 의존성 배열로 "언제 다시 실행할지"를 제어한다.
- 시작한 작업은 반환 함수로 반드시 정리해야 한다.
직접 해보기
- 화면에 뜨자마자 콘솔에 메시지를 출력하는 컴포넌트 만들어보기
다음 챕터 예고
여기까지 오면 React의 핵심 도구(state, 참조값, useEffect)를 한 바퀴 돌았습니다.
다음에는 이 도구들을 합쳐서 투두리스트를 직접 만들어 보겠습니다.