이미지 로딩 중...
CodeDeck AI
2025. 11. 8. · 1 Views
React Hooks 완벽 가이드
React Hooks의 핵심 개념부터 고급 활용까지 다루는 실전 가이드입니다. useState, useEffect, 커스텀 훅 등 실무에서 자주 사용하는 패턴을 예제와 함께 소개합니다.
들어가며
이 글에서는 React Hooks 완벽 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- useState_기본_사용법
- useEffect_생명주기_관리
- useEffect_클린업_함수
- useContext_전역_상태_관리
- useRef_DOM_접근
- useMemo_연산_최적화
- useCallback_함수_메모이제이션
- 커스텀_Hook_기본
- useReducer_복잡한_상태_관리
- 커스텀_Hook_데이터_페칭
1. useState_기본_사용법
개요
컴포넌트에서 상태를 관리하는 가장 기본적인 Hook입니다. 상태 값과 상태를 업데이트하는 함수를 반환합니다.
코드 예제
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
클릭 횟수: {count}
</button>
);
}
설명
useState(0)으로 초기값 0을 설정하고, setCount로 상태를 업데이트합니다. 버튼 클릭 시 count가 1씩 증가합니다.
2. useEffect_생명주기_관리
개요
컴포넌트의 사이드 이펙트(API 호출, 구독 등)를 처리하는 Hook입니다. 의존성 배열로 실행 시점을 제어할 수 있습니다.
코드 예제
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => setUser(data));
}, [userId]);
return <div>{user?.name}</div>;
}
설명
userId가 변경될 때마다 API를 호출하여 사용자 정보를 가져옵니다. 의존성 배열 [userId]로 실행 조건을 지정합니다.
3. useEffect_클린업_함수
개요
useEffect에서 반환하는 함수는 컴포넌트가 언마운트되거나 다음 effect 실행 전에 호출됩니다. 구독 해제나 타이머 정리에 사용합니다.
코드 예제
import { useEffect } from 'react';
function Timer() {
useEffect(() => {
const timer = setInterval(() => {
console.log('1초마다 실행');
}, 1000);
return () => clearInterval(timer);
}, []);
return <div>타이머 실행 중</div>;
}
설명
컴포넌트가 마운트될 때 타이머를 시작하고, 언마운트될 때 클린업 함수로 타이머를 정리합니다.
4. useContext_전역_상태_관리
개요
Context API와 함께 사용하여 props drilling 없이 전역 상태를 관리합니다. 여러 컴포넌트에서 같은 데이터를 공유할 때 유용합니다.
코드 예제
import { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function Button() {
const theme = useContext(ThemeContext);
return (
<button className={theme}>
테마: {theme}
</button>
);
}
설명
ThemeContext에서 현재 테마 값을 가져와 버튼에 적용합니다. Provider로 감싸진 모든 하위 컴포넌트에서 접근 가능합니다.
5. useRef_DOM_접근
개요
DOM 요소에 직접 접근하거나 리렌더링 없이 값을 저장할 때 사용합니다. 값이 변경되어도 리렌더링이 발생하지 않습니다.
코드 예제
import { useRef } from 'react';
function InputFocus() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus();
};
return (
<>
<input ref={inputRef} />
<button onClick={handleClick}>포커스</button>
</>
);
}
설명
useRef로 input 요소를 참조하고, 버튼 클릭 시 inputRef.current.focus()로 직접 포커스를 설정합니다.
6. useMemo_연산_최적화
개요
비용이 큰 연산 결과를 메모이제이션하여 불필요한 재계산을 방지합니다. 의존성 배열의 값이 변경될 때만 다시 계산합니다.
코드 예제
import { useMemo, useState } from 'react';
function ExpensiveComponent({ items }) {
const [count, setCount] = useState(0);
const total = useMemo(() => {
return items.reduce((sum, item) => sum + item.price, 0);
}, [items]);
return <div>총액: {total}</div>;
}
설명
items 배열이 변경될 때만 총액을 다시 계산합니다. count가 변경되어도 total은 재계산되지 않아 성능이 향상됩니다.
7. useCallback_함수_메모이제이션
개요
함수를 메모이제이션하여 불필요한 함수 재생성을 방지합니다. 자식 컴포넌트에 콜백을 전달할 때 리렌더링을 줄일 수 있습니다.
코드 예제
import { useCallback, useState } from 'react';
function TodoList() {
const [todos, setTodos] = useState([]);
const addTodo = useCallback((text) => {
setTodos(prev => [...prev, { id: Date.now(), text }]);
}, []);
return <TodoForm onAdd={addTodo} />;
}
설명
addTodo 함수는 컴포넌트가 리렌더링되어도 동일한 참조를 유지합니다. TodoForm이 불필요하게 리렌더링되는 것을 방지합니다.
8. 커스텀_Hook_기본
개요
반복되는 로직을 재사용 가능한 Hook으로 분리합니다. use로 시작하는 이름을 사용하고 다른 Hook을 조합할 수 있습니다.
코드 예제
import { useState, useEffect } from 'react';
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
설명
윈도우 너비를 추적하는 로직을 커스텀 Hook으로 분리했습니다. 여러 컴포넌트에서 const width = useWindowWidth()로 재사용할 수 있습니다.
9. useReducer_복잡한_상태_관리
개요
useState보다 복잡한 상태 로직을 관리할 때 사용합니다. Redux와 유사한 패턴으로 액션을 통해 상태를 업데이트합니다.
코드 예제
import { useReducer } from 'react';
function reducer(state, action) {
switch(action.type) {
case 'increment': return { count: state.count + 1 };
case 'decrement': return { count: state.count - 1 };
default: return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return <button onClick={() => dispatch({type: 'increment'})}>{state.count}</button>;
}
설명
reducer 함수로 상태 업데이트 로직을 분리하고, dispatch로 액션을 전달합니다. 여러 상태가 연관될 때 유용합니다.
10. 커스텀_Hook_데이터_페칭
개요
API 호출 로직을 재사용 가능한 Hook으로 만듭니다. 로딩 상태와 에러 처리를 포함하여 완전한 데이터 페칭 솔루션을 제공합니다.
코드 예제
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => { setData(data); setLoading(false); });
}, [url]);
return { data, loading };
}
설명
URL을 받아서 데이터를 가져오는 로직을 커스텀 Hook으로 캡슐화했습니다. 어떤 컴포넌트에서든 간단하게 사용할 수 있습니다.
마치며
이번 글에서는 React Hooks 완벽 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#React #Hooks #useState #useEffect #CustomHooks