React Hooks는 함수형 컴포넌트에서 상태와 생명주기 기능을 사용할 수 있게 해주는 API다. React 16.8에서 도입되어 클래스 컴포넌트를 대체하며, 로직 재사용을 컴포저블한 방식으로 가능하게 한다.
기본 Hooks
useState
tsx
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const [user, setUser] = useState<{ name: string } | null>(null);
return (
<div>
<button onClick={() => setCount(prev => prev + 1)}>{count}</button>
<button onClick={() => setUser({ name: 'Alice' })}>Set User</button>
</div>
);
}
useEffect
tsx
import { useEffect, useState } from 'react';
function DataFetcher({ id }: { id: number }) {
const [data, setData] = useState(null);
useEffect(() => {
let cancelled = false;
fetch(`/api/items/${id}`)
.then(r => r.json())
.then(d => { if (!cancelled) setData(d); });
return () => { cancelled = true; }; // 클린업
}, [id]); // id 변경 시 재실행
return <div>{JSON.stringify(data)}</div>;
}
useCallback / useMemo
tsx
import { useCallback, useMemo } from 'react';
function ExpensiveComponent({ items, filter }: Props) {
// 함수 메모이제이션 (자식 컴포넌트 리렌더링 방지)
const handleClick = useCallback((id: number) => {
console.log(id);
}, []);
// 값 메모이제이션 (재계산 방지)
const filtered = useMemo(
() => items.filter(item => item.category === filter),
[items, filter]
);
return <List items={filtered} onClick={handleClick} />;
}
커스텀 Hook
tsx
// useLocalStorage 커스텀 Hook
function useLocalStorage<T>(key: string, initialValue: T) {
const [value, setValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch { return initialValue; }
});
const setItem = (newValue: T) => {
setValue(newValue);
window.localStorage.setItem(key, JSON.stringify(newValue));
};
return [value, setItem] as const;
}
// 사용
const [theme, setTheme] = useLocalStorage('theme', 'light');
Hooks 규칙
- 1.최상위에서만 호출 (반복문/조건문 내부 금지)
- 2.React 함수 컴포넌트 또는 커스텀 Hook에서만 호출
관련 개념