728x90
반응형
🎯 React Hook이란?
💡 핵심 개념
React Hook = 공통 JavaScript 모듈 + React 상태 관리
함수형 컴포넌트에서 상태(state)와 생명주기(lifecycle) 기능을 사용할 수 있게 해주는 특별한 함수입니다.
기존에는 클래스 컴포넌트에서만 가능했던 상태 관리를 함수형 컴포넌트에서도 할 수 있게 되면서, React 개발이 훨씬 간단해졌습니다.
⏰ 언제 사용하는가?
👤 상태 관리가 필요할 때
- 사용자 로그인 상태
- 폼 입력값 관리
- API 로딩 상태
- 테마 설정 (다크/라이트)
🔄 로직 공유가 필요할 때
- 여러 페이지에서 동일한 기능
- 비슷한 상태 관리 로직 반복
- 복잡한 비즈니스 로직 재사용
⚡ 사이드 이펙트 처리
- API 호출
- 타이머 설정
- DOM 조작
- 구독(subscription) 관리
💡 왜 사용하는가?
🔄
코드 재사용성
한 번 작성한 Hook을 여러 컴포넌트에서 재사용할 수 있어 개발 효율성이 크게 향상됩니다.
🎯
로직 분리
UI 로직과 비즈니스 로직을 깔끔하게 분리하여 코드의 가독성과 유지보수성을 높입니다.
🧪
테스트 용이성
Hook 단위로 독립적인 테스트가 가능하여 안정적인 코드 작성을 도와줍니다.
🤝
상태 공유
여러 컴포넌트가 동일한 상태를 효율적으로 공유할 수 있습니다.
✅ 장점
- 함수형 컴포넌트에서 상태 관리 가능
- 로직 재사용으로 개발 시간 단축
- 클래스 컴포넌트보다 간결한 코드
- 성능 최적화가 쉬움
- 커뮤니티에서 다양한 커스텀 Hook 제공
⚠️ 주의사항
- Hook 규칙을 반드시 지켜야 함
- 처음에는 학습 곡선이 있음
- 잘못 사용하면 무한 렌더링 발생 가능
- 의존성 배열 관리가 중요
⚖️ 일반 JS 모듈과의 차이점
📦 일반 JavaScript 모듈
utils/loginHelper.js
export function checkLoginStatus() {
// 매번 새로 API 호출
return fetch('/api/user/status');
}
export function getUserInfo() {
// 매번 새로 데이터 요청
return fetch('/api/user/info');
}
특징:
- 🔴 단순히 함수들만 모아놓음
- 🔴 상태(데이터)를 저장하지 않음
- 🔴 매번 호출할 때마다 새로 실행
- 🔴 메모리에 데이터를 유지하지 않음
🎣 React Hook
hooks/useAuth.js
export function useAuth() {
const [user, setUser] = useState(null); // 상태 저장
const [loading, setLoading] = useState(true); // 로딩 상태
useEffect(() => {
// 컴포넌트 마운트 시 한 번만 실행
checkLoginStatus();
}, []);
const signOut = () => {
setUser(null);
// 로그아웃 로직
};
return { user, loading, signOut };
}
특징:
- 🟢 함수 + 상태 관리 + React 생명주기
- 🟢 여러 컴포넌트가 동일한 상태 공유
- 🟢 상태를 메모리에 유지
- 🟢 한 번 로그인하면 다른 페이지에서도 유지
🔧 실무 활용 예시
🔐 1. 인증 상태 관리 (useAuth)
가장 많이 사용되는 Hook 중 하나로, 로그인 상태를 전역적으로 관리합니다.
hooks/useAuth.js
function useAuth() {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
// 로그인 체크
const checkAuth = async () => {
try {
const response = await fetch('/api/me');
if (response.ok) {
const userData = await response.json();
setUser(userData);
}
} catch (error) {
console.error('인증 확인 실패:', error);
} finally {
setIsLoading(false);
}
};
useEffect(() => {
checkAuth();
}, []);
const signOut = async () => {
await fetch('/api/logout', { method: 'POST' });
setUser(null);
};
return { user, isLoading, signOut, isAuthenticated: !!user };
}
// 사용 예시
function Header() {
const { user, isLoading, signOut, isAuthenticated } = useAuth();
if (isLoading) return
{isAuthenticated ? (
);
}
로딩중...
;
return (
안녕하세요, {user.name}님!
) : (
로그인
)}
📡 2. API 데이터 가져오기 (useFetch)
API 호출과 관련된 로딩, 에러, 데이터 상태를 한번에 관리합니다.
hooks/useFetch.js
function useFetch(url, options = {}) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
setError(null);
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
if (url) {
fetchData();
}
}, [url]);
const refetch = () => {
if (url) {
fetchData();
}
};
return { data, loading, error, refetch };
}
// 사용 예시
function UserList() {
const { data: users, loading, error, refetch } = useFetch('/api/users');
if (loading) return
사용자 목록 로딩중...
;
if (error) return 오류: {error}
;
return (
-
{users?.map(user => (
- {user.name} ))}
💾 3. 로컬 스토리지 관리 (useLocalStorage)
브라우저 로컬 스토리지와 React 상태를 동기화합니다.
hooks/useLocalStorage.js
function useLocalStorage(key, initialValue) {
// 초기값 설정
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error('로컬 스토리지 읽기 실패:', error);
return initialValue;
}
});
// 값 저장 함수
const setValue = (value) => {
try {
// 함수가 전달된 경우 실행
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error('로컬 스토리지 저장 실패:', error);
}
};
return [storedValue, setValue];
}
// 사용 예시
function Settings() {
const [theme, setTheme] = useLocalStorage('theme', 'light');
const [language, setLanguage] = useLocalStorage('language', 'ko');
return (
);
}
설정
✨ 베스트 프랙티스
📋
Hook 규칙 준수
- 최상위 레벨에서만 호출
- 조건문, 반복문 내부에서 호출 금지
- React 함수에서만 사용
🎯
의존성 배열 관리
- useEffect의 의존성 배열 정확히 명시
- 불필요한 리렌더링 방지
- ESLint 플러그인 활용
🔧
커스텀 Hook 네이밍
- 반드시 'use'로 시작
- 명확하고 설명적인 이름 사용
- 기능을 잘 표현하는 이름 선택
⚡
성능 최적화
- useMemo, useCallback 적절히 활용
- 불필요한 상태 업데이트 피하기
- 메모리 누수 방지
🎉 결론
🎯 핵심 정리
React Hook은 상태를 가지고 있으면서 재사용 가능한 로직이 필요할 때 사용합니다.
✅ Hook 사용 권장
- 상태 관리가 필요한 로직
- 컴포넌트 간 상태 공유
- 사이드 이펙트 처리
- 복잡한 비즈니스 로직
📦 일반 JS 모듈 사용
- 단순 유틸리티 함수
- 상태가 없는 계산 로직
- 데이터 변환 함수
- 상수 값들
🚀 올바른 Hook 사용으로 더욱 깔끔하고 유지보수하기 쉬운 React 애플리케이션을 개발해보세요!
728x90
'Tech Notes' 카테고리의 다른 글
| OAuth 2.0플로우차트 (0) | 2025.09.16 |
|---|---|
| React에서 무한 루프 발생 원인 (0) | 2025.09.11 |
| Blob URL vs Presigned URL: 웹 개발자를 위한 완전 가이드 (0) | 2025.09.11 |
| Git Cherry-pick 이란? (0) | 2025.09.10 |
| 딥링크(Deep Link)란 무엇인가? - 모바일 앱과 웹의 연결고리 (0) | 2025.09.09 |