우당탕탕
React useEffect 의존성 배열 때문에 삽질한 경험과 해결 방법 본문
React 개발하면서 useEffect 훅의 의존성 배열 때문에 생각보다 고생을 많이 했어요. 저도 처음엔 왜 이걸 써야 하는지, 어떤 값들을 넣어야 하는지 감이 안 와서 값이 안 바뀌거나 무한루프에 빠지곤 했거든요.
이 글에선 제가 겪었던 삽질들, 그 원인 그리고 의존성 배열을 제대로 사용하는 방법을 차근차근 정리해봤습니다. 저처럼 헷갈리는 분들께 큰 도움이 될 거예요.
React useEffect 의존성 배열 왜 중요한지 삽질 후기 관련 정보
useEffect 의존성 배열, 사실 뭐길래?
사실 useEffect 안에 넣은 코드는 컴포넌트가 렌더링될 때마다 실행돼요. 그런데 의존성 배열에 넣은 값들이 변할 때만 실행하도록 제어할 수 있거든요. 의존성 배열을 비워 두면 마운트 시에만 실행되고, 배열에 상태나 props 변수를 넣으면 그 값이 변할 때마다 실행됩니다.
이게 참 좋은 기능인데 여기서 많이 삽질하는 이유는, 어떤 값을 넣어야 하는지 헷갈리고, 누락하면 의도하지 않은 동작이 생기기 때문이에요.
의존성 배열을 잘못 써서 막혔던 경험
처음에 저는 이렇게 썼는데, 무한루프가 났어요.
const [count, setCount] = React.useState(0);
React.useEffect(() => {
// count가 변할 때마다 상태를 바꾸는 함수 호출
setCount(prev => prev + 1);
}, [count]);
처음에는 count가 바뀔 때만 실행돼서 괜찮다고 생각했는데, setCount 때문에 count가 계속 바뀌면서 useEffect도 계속 실행돼서 무한루프가 됐죠. 이걸 몰라서 한참 헤맸어요.
또, 의존성 배열을 아예 빈 배열로 두면 원하는 값이 바뀌어도 effect가 재실행 안돼서 데이터가 업데이트 안되는 문제도 발생했습니다.
제가 쓴 의존성 배열 관리법, 이렇게 하면 됩니다
제가 찾아낸 가장 중요한 팁은 “effect 안에서 사용하는 모든 상태와 props는 의존성 배열에 꼭 넣어야 한다”는 거였어요. 그래야 React가 언제 effect를 다시 실행할지 정확히 알거든요.
근데 함수나 객체 같은 참조형 데이터는 매번 새로 생성되니까, 무한루프의 원인이 되기 쉬워요. 그래서 useCallback이나 useMemo를 써서 의존성을 안정화하는 게 중요하다는 것도 알게 됐죠.
다음은 제가 쓴 예시 코드입니다.
const MyComponent = ({ userId }) => {
const [userData, setUserData] = React.useState(null);
// 데이터를 불러오는 함수, useCallback으로 감싸서 참조 안정화
const fetchUserData = React.useCallback(() => {
fetch(`https://api.example.com/users/${userId}`)
.then(res => res.json())
.then(data => setUserData(data));
}, [userId]);
// userId나 fetchUserData가 바뀌면 effect 재실행
React.useEffect(() => {
fetchUserData();
}, [fetchUserData]);
return (
<div>
{userData ? <pre>{JSON.stringify(userData, null, 2)}</pre> : '로딩 중...'}
</div>
);
};
이렇게 하면 userId가 바뀔 때마다 fetchUserData가 새로 만들어지고, 그 덕분에 useEffect가 정확하게 실행됩니다.
React useEffect 의존성 배열 왜 중요한지 삽질 후기 관련 정보
여기서 삽질했던 부분들, 왜 그랬는지
한번은 useEffect 의존성 배열에 함수(fetchUserData)를 직접 넣지 않고 빈 배열로 두고, 함수 안에서 userId를 참조해서 데이터를 가져오게 했어요. 그랬더니 userId가 바뀌어도 effect가 다시 안 실행되더라고요.
React.useEffect(() => {
fetch(`https://api.example.com/users/${userId}`)
.then(res => res.json())
.then(data => setUserData(data));
}, []); // userId 빠짐
이 문제는 userId를 의존성 배열에 넣어야 하는데, 안 넣어서 생긴 거였어요. 훅이 마운트 때만 실행되니, userId가 업데이트돼도 재호출을 안 했던 거죠.
그리고 또, 함수 내부에서 상태를 업데이트 하는 경우, 그 상태도 의존성 배열에 넣거나, 함수 자체를 useCallback으로 감싸서 안정화해야 무한루프 없이 잘 돌아갑니다.
조금 더 알면 유용한 트릭들
의존성 배열에 대해 ESLint가 알려주는 게 있으니 꼭 ESLint 플러그인을 활성화해보세요. 자칫 빠뜨린 의존성을 찾아서 알려줘서 도움이 많이 됩니다.
그리고 참조형 데이터(객체, 배열, 함수)를 의존성 배열에 넣으면 매번 새로운 참조라서 effect가 예상보다 많이 실행될 수 있어요. 그래서 이렇게 참조를 안정화 하는 게 관건입니다.
자주 물어보시는 것들
Q. 의존성 배열에 모든 상태를 넣으면 성능에 문제 없나요?
A. 상태가 많아질수록 effect가 자주 실행될 수 있어서, 필요하지 않은 값은 빼야 합니다. 하지만 대부분 상태는 넣는 게 맞고, 불필요한 실행은 useMemo, useCallback으로 최적화하세요.
Q. 의존성 배열에 함수를 직접 넣지 말라는 얘기도 있는데 왜인가요?
A. 함수는 매 렌더링마다 새로 생성되기 때문에, 그냥 넣으면 effect가 너무 자주 실행될 수 있어요. 그래서 useCallback으로 감싸서 함수 참조를 유지하는 걸 권장해요.
React useEffect 의존성 배열 왜 중요한지 삽질 후기 관련 정보
마무리하자면, useEffect 의존성 배열은 리액트 컴포넌트의 업데이트 주기를 세밀하게 제어하는 중요한 도구예요. 저도 삽질하면서 배운 만큼 제대로 활용하면 데이터 일관성과 성능 향상에 큰 도움이 됩니다. 다음에는 useMemo, useCallback과 함께 더 나은 최적화 팁도 공유할게요.
'언어 > JavaScript' 카테고리의 다른 글
| Vite로 마이그레이션하면서 막혔던 설정, 이렇게 해결했습니다 (0) | 2026.05.31 |
|---|---|
| React useEffect 의존성 배열 때문에 겪은 삽질과 해결 과정 이야기 (0) | 2026.05.30 |
| JavaScript async await 쓰면서 제가 자주 실수한 패턴들 이야기해볼게요 (0) | 2026.05.25 |
| React useEffect 의존성 배열 때문에 고생하다가 알게 된 핵심 포인트 (0) | 2026.05.17 |
| Next.js 13 App Router 마이그레이션 직접 해보니 생각보다 이랬어요 (1) | 2026.05.16 |
