본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 11. 4. · 14 Views
React 기초부터 심화까지 완벽 가이드
React의 핵심 개념부터 고급 패턴까지 실전 예제로 학습합니다. Hooks, 성능 최적화, 커스텀 훅, Context API 등 모던 React 개발에 필요한 모든 것을 다룹니다.
들어가며
이 글에서는 React 기초부터 심화까지 완벽 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.
목차
- useState_기본_상태_관리
- useEffect_부수효과_처리
- useMemo_계산_결과_메모이제이션
- useCallback_함수_메모이제이션
- useContext_전역_상태_관리
- useReducer_복잡한_상태_로직
- useRef_DOM_접근과_값_보존
- Custom_Hook_로직_재사용
- React_memo_컴포넌트_최적화
- Error_Boundary_에러_처리
- useLayoutEffect_동기적_DOM_업데이트
- Portal_외부_DOM_렌더링
1. useState 기본 상태 관리
개요
컴포넌트의 상태를 관리하는 가장 기본적인 Hook입니다. 상태가 변경되면 컴포넌트가 자동으로 리렌더링됩니다.
코드 예제
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
설명
useState는 [현재값, 업데이트함수] 배열을 반환하며, setCount를 호출하면 컴포넌트가 리렌더링됩니다.
2. useEffect 부수효과 처리
개요
컴포넌트가 렌더링될 때 부수효과(데이터 fetching, 구독 등)를 처리합니다. 의존성 배열로 실행 조건을 제어합니다.
코드 예제
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(setUser);
}, [userId]);
return <div>{user?.name}</div>;
}
설명
userId가 변경될 때마다 API를 호출하며, 빈 배열([])을 전달하면 마운트 시 한 번만 실행됩니다.
3. useMemo 계산 결과 메모이제이션
개요
비용이 큰 계산 결과를 캐싱하여 불필요한 재계산을 방지합니다. 성능 최적화의 핵심 도구입니다.
코드 예제
function ProductList({ products, filter }) {
const filteredProducts = useMemo(() => {
return products.filter(p =>
p.name.toLowerCase().includes(filter.toLowerCase())
);
}, [products, filter]);
return <div>{filteredProducts.map(p => <div key={p.id}>{p.name}</div>)}</div>;
}
설명
products나 filter가 변경될 때만 필터링을 다시 수행하므로, 불필요한 연산을 줄입니다.
4. useCallback 함수 메모이제이션
개요
함수 자체를 메모이제이션하여 자식 컴포넌트의 불필요한 리렌더링을 방지합니다.
코드 예제
function TodoList({ todos }) {
const [filter, setFilter] = useState('');
const handleDelete = useCallback((id) => {
deleteTodo(id);
}, []);
return todos.map(todo =>
<TodoItem key={todo.id} onDelete={handleDelete} />
);
}
설명
handleDelete 함수가 매번 새로 생성되지 않아 TodoItem 컴포넌트의 props가 변경되지 않습니다.
5. useContext 전역 상태 관리
개요
Context API를 사용하여 props drilling 없이 컴포넌트 트리 전체에서 데이터를 공유합니다.
코드 예제
const ThemeContext = createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <div className={theme}>Current theme: {theme}</div>;
}
설명
Toolbar은 중간 컴포넌트를 거치지 않고 직접 ThemeContext의 값을 읽을 수 있습니다.
6. useReducer 복잡한 상태 로직
개요
복잡한 상태 로직을 reducer 함수로 분리하여 관리합니다. Redux와 유사한 패턴입니다.
코드 예제
function cartReducer(state, action) {
switch(action.type) {
case 'ADD': return [...state, action.item];
case 'REMOVE': return state.filter(i => i.id !== action.id);
default: return state;
}
}
function Cart() {
const [items, dispatch] = useReducer(cartReducer, []);
return <button onClick={() => dispatch({type: 'ADD', item: {id: 1}})}>추가</button>;
}
설명
dispatch로 액션을 전달하면 reducer가 새로운 상태를 계산하여 반환합니다.
7. useRef DOM 접근과 값 보존
개요
DOM 요소에 직접 접근하거나, 리렌더링 없이 값을 보존할 때 사용합니다.
코드 예제
function TextInput() {
const inputRef = useRef(null);
const renderCount = useRef(0);
useEffect(() => {
renderCount.current += 1;
inputRef.current.focus();
});
return <input ref={inputRef} placeholder="렌더: {renderCount.current}" />;
}
설명
inputRef로 DOM에 접근하고, renderCount는 리렌더링을 유발하지 않으면서 값을 유지합니다.
8. Custom Hook 로직 재사용
개요
반복되는 로직을 커스텀 Hook으로 추출하여 여러 컴포넌트에서 재사용합니다.
코드 예제
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 };
}
설명
useFetch를 여러 컴포넌트에서 호출하여 데이터 fetching 로직을 재사용할 수 있습니다.
9. React memo 컴포넌트 최적화
개요
props가 변경되지 않으면 컴포넌트 리렌더링을 건너뛰는 고차 컴포넌트입니다.
코드 예제
const ExpensiveComponent = React.memo(({ data }) => {
console.log('렌더링!');
return (
<div>
{data.map(item => <div key={item.id}>{item.name}</div>)}
</div>
);
});
설명
부모 컴포넌트가 리렌더링되어도 data prop이 동일하면 ExpensiveComponent는 리렌더링되지 않습니다.
10. Error Boundary 에러 처리
개요
자식 컴포넌트에서 발생한 에러를 포착하여 fallback UI를 보여줍니다.
코드 예제
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
render() {
if (this.state.hasError) return <h1>에러 발생!</h1>;
return this.props.children;
}
}
설명
ErrorBoundary로 감싼 컴포넌트에서 에러가 발생하면 앱이 중단되지 않고 fallback UI를 보여줍니다.
11. useLayoutEffect 동기적 DOM 업데이트
개요
DOM 변경 직후 동기적으로 실행되어 화면 깜빡임을 방지합니다.
코드 예제
function Tooltip({ text }) {
const ref = useRef(null);
const [position, setPosition] = useState(0);
useLayoutEffect(() => {
const rect = ref.current.getBoundingClientRect();
setPosition(rect.width);
}, [text]);
return <div ref={ref} style={{ left: position }}>{text}</div>;
}
설명
useEffect와 달리 브라우저가 화면을 그리기 전에 실행되어 레이아웃 계산에 적합합니다.
12. Portal 외부 DOM 렌더링
개요
컴포넌트를 부모 DOM 계층 외부에 렌더링합니다. 모달, 툴팁 등에 유용합니다.
코드 예제
function Modal({ children }) {
return ReactDOM.createPortal(
<div className="modal">
{children}
</div>,
document.getElementById('modal-root')
);
}
설명
Modal은 #modal-root에 렌더링되지만 React 트리상으로는 부모 컴포넌트의 자식으로 동작합니다.
마치며
이번 글에서는 React 기초부터 심화까지 완벽 가이드에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.
관련 태그
#React #Hooks #useEffect #useMemo #CustomHooks
이 카드뉴스가 포함된 코스
댓글 (0)
함께 보면 좋은 카드 뉴스
서비스 메시 완벽 가이드
마이크로서비스 간 통신을 안전하고 효율적으로 관리하는 서비스 메시의 핵심 개념부터 실전 도입까지, 초급 개발자를 위한 완벽한 입문서입니다. Istio와 Linkerd 비교, 사이드카 패턴, 실무 적용 노하우를 담았습니다.
EFK 스택 로깅 완벽 가이드
마이크로서비스 환경에서 로그를 효과적으로 수집하고 분석하는 EFK 스택(Elasticsearch, Fluentd, Kibana)의 핵심 개념과 실전 활용법을 초급 개발자도 쉽게 이해할 수 있도록 정리한 가이드입니다.
Grafana 대시보드 완벽 가이드
실시간 모니터링의 핵심, Grafana 대시보드를 처음부터 끝까지 배워봅니다. Prometheus 연동부터 알람 설정까지, 초급 개발자도 쉽게 따라할 수 있는 실전 가이드입니다.
분산 추적 완벽 가이드
마이크로서비스 환경에서 요청의 전체 흐름을 추적하는 분산 추적 시스템의 핵심 개념을 배웁니다. Trace, Span, Trace ID 전파, 샘플링 전략까지 실무에 필요한 모든 것을 다룹니다.
CloudFront CDN 완벽 가이드
AWS CloudFront를 활용한 콘텐츠 배포 최적화 방법을 실무 관점에서 다룹니다. 배포 생성부터 캐시 설정, HTTPS 적용까지 단계별로 알아봅니다.