React에서 useEffect 의존성 배열을 올바르게 사용하는 방법
1250 조회
1 답변
2024. 1. 15.•김개발
React의 useEffect Hook을 사용할 때 의존성 배열을 어떻게 올바르게 설정해야 하나요?
특히 다음과 같은 상황에서 어떻게 해야 할지 궁금합니다:
1. 객체나 배열을 의존성으로 사용할 때
2. 함수를 의존성으로 사용할 때
3. 무한 루프를 방지하는 방법
실제 코드 예시와 함께 설명해주시면 감사하겠습니다.
답변 (1)
AI Assistant
2024. 1. 15.
채택됨
# React useEffect 의존성 배열 완벽 가이드
React의 `useEffect` Hook에서 의존성 배열을 올바르게 사용하는 방법을 단계별로 설명드리겠습니다.
## 🔍 기본 원칙
의존성 배열에는 **effect 내부에서 사용하는 모든 값**을 포함해야 합니다.
```jsx
function MyComponent({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]); // userId를 의존성에 포함
return <div>{user?.name}</div>;
}
```
## 🎯 객체/배열 의존성 처리
### 문제가 되는 코드:
```jsx
function BadExample({ config }) {
useEffect(() => {
// config 객체가 매번 새로 생성되면 무한 루프 발생
doSomething(config);
}, [config]);
}
```
### 해결 방법:
```jsx
function GoodExample({ config }) {
// 1. useMemo로 객체 메모이제이션
const memoizedConfig = useMemo(() => config, [config.key, config.value]);
useEffect(() => {
doSomething(memoizedConfig);
}, [memoizedConfig]);
// 2. 또는 필요한 속성만 의존성에 추가
useEffect(() => {
doSomething(config);
}, [config.key, config.value]);
}
```
## 🛠️ 함수 의존성 처리
### useCallback 사용:
```jsx
function ComponentWithFunction({ id }) {
const fetchData = useCallback(async () => {
const response = await fetch(`/api/data/${id}`);
return response.json();
}, [id]);
useEffect(() => {
fetchData().then(setData);
}, [fetchData]);
}
```
### 함수를 effect 내부로 이동:
```jsx
function BetterApproach({ id }) {
useEffect(() => {
async function fetchData() {
const response = await fetch(`/api/data/${id}`);
const data = await response.json();
setData(data);
}
fetchData();
}, [id]); // 함수가 내부에 있으므로 의존성에서 제외
}
```
## 🚫 무한 루프 방지
### 1. 불필요한 의존성 제거
```jsx
function Component() {
const [count, setCount] = useState(0);
useEffect(() => {
// setCount는 안정적이므로 의존성에 포함하지 않아도 됨
const timer = setInterval(() => {
setCount(prev => prev + 1);
}, 1000);
return () => clearInterval(timer);
}, []); // 빈 배열로 한 번만 실행
}
```
### 2. useRef로 최신 값 참조
```jsx
function Component({ callback }) {
const callbackRef = useRef(callback);
// 최신 callback을 ref에 저장
useEffect(() => {
callbackRef.current = callback;
});
useEffect(() => {
const interval = setInterval(() => {
callbackRef.current(); // 항상 최신 callback 호출
}, 1000);
return () => clearInterval(interval);
}, []); // callback이 변경되어도 effect는 재실행되지 않음
}
```
## 📚 베스트 프랙티스
1. **ESLint 규칙 활용**: `react-hooks/exhaustive-deps` 규칙 사용
2. **의존성 최소화**: 꼭 필요한 값만 의존성에 포함
3. **함수형 업데이트**: `setState(prev => prev + 1)` 형태 사용
4. **커스텀 Hook**: 복잡한 로직은 커스텀 Hook으로 분리
이러한 패턴들을 따르면 useEffect를 안전하고 효율적으로 사용할 수 있습니다! 🚀
답변 작성하기
도움이 되는 답변을 작성해주세요. 마크다운 문법을 사용할 수 있습니다.