React Hooks
useState
컴포넌트에 상태를 추가할 수 있게 해주는 Hook입니다. 상태값과 상태를 업데이트하는 함수를 반환합니다.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
);
}
Count: {count}
useEffect
컴포넌트에서 사이드 이펙트를 수행할 수 있게 해주는 Hook입니다. 데이터 가져오기, 구독 설정, DOM 수동 조작 등에 사용됩니다.
import { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser(userId).then(setUser);
}, [userId]); // userId가 변경될 때만 실행
return user ?
{user.name}
: Loading...
;
}useContext
React Context를 구독하고 해당 컨텍스트의 현재 값을 읽을 수 있게 해주는 Hook입니다. prop drilling을 피할 수 있습니다.
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';
function Button() {
const theme = useContext(ThemeContext);
return (
);
}
useRef
DOM 요소에 직접 접근하거나 렌더링 간에 값을 유지해야 할 때 사용하는 Hook입니다. .current 프로퍼티로 값에 접근합니다.
import { useRef, useEffect } from 'react';
function TextInput() {
const inputRef = useRef(null);
useEffect(() => {
// 컴포넌트가 마운트되면 input에 포커스
inputRef.current.focus();
}, []);
return ;
}
useReducer
복잡한 상태 로직을 관리할 때 useState 대신 사용할 수 있는 Hook입니다. 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:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
Count: {state.count}
);
}useMemo
비용이 많이 드는 계산을 메모이제이션하여 성능을 최적화하는 Hook입니다. 의존성 배열의 값이 변경될 때만 재계산됩니다.
import { useMemo } from 'react';
function ExpensiveComponent({ items }) {
const expensiveValue = useMemo(() => {
return items.reduce((sum, item) => sum + item.value, 0);
}, [items]); // items가 변경될 때만 재계산
return
Total: {expensiveValue}
;
}useCallback
함수를 메모이제이션하여 불필요한 리렌더링을 방지하는 Hook입니다. 자식 컴포넌트에 함수를 props로 전달할 때 유용합니다.
import { useCallback, useState } from 'react';
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(c => c + 1);
}, []); // 의존성이 없으므로 함수가 재생성되지 않음
return ;
}
Custom Hooks
재사용 가능한 로직을 추출하여 여러 컴포넌트에서 공유할 수 있는 사용자 정의 Hook입니다. 'use'로 시작하는 함수로 만듭니다.
import { useState, useEffect } from 'react';
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setValue = (value) => {
try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(error);
}
};
return [storedValue, setValue];
}
// 사용 예시
function App() {
const [name, setName] = useLocalStorage('name', '');
return (
setName(e.target.value)}
/>
);
}
Event Handling
onClick
클릭 이벤트를 처리하는 가장 기본적인 이벤트 핸들러입니다. 버튼, 링크 등의 클릭 동작을 처리할 때 사용됩니다.
function Button() {
const handleClick = (event) => {
event.preventDefault();
console.log('버튼이 클릭되었습니다!');
};
return (
);
}
onChange
입력 필드의 값이 변경될 때 발생하는 이벤트를 처리합니다. 폼 입력을 실시간으로 추적할 때 사용됩니다.
function TextInput() {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
};
return (
);
}
onSubmit
폼이 제출될 때 발생하는 이벤트를 처리합니다. 폼 데이터를 서버로 전송하거나 유효성 검사를 수행할 때 사용됩니다.
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
console.log('로그인 시도:', { email, password });
};
return (
);
}
onMouseEnter/onMouseLeave
마우스가 요소에 진입하거나 떠날 때 발생하는 이벤트를 처리합니다. 호버 효과나 툴팁 표시에 사용됩니다.
function HoverCard() {
const [isHovered, setIsHovered] = useState(false);
return (
setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
style={{
backgroundColor: isHovered ? '#f0f0f0' : 'white',
padding: '20px',
border: '1px solid #ccc'
}}
>
{isHovered ? '마우스가 올라와 있습니다!' : '마우스를 올려보세요'}
);
}Performance Optimization
React.memo
컴포넌트를 메모이제이션하여 props가 변경되지 않으면 리렌더링을 방지합니다. 함수형 컴포넌트의 성능을 최적화할 때 사용됩니다.
import React from 'react';
const ExpensiveComponent = React.memo(function ExpensiveComponent({ data }) {
console.log('ExpensiveComponent 렌더링');
return (
{data.map(item => (
);
});
// props가 같으면 리렌더링되지 않음{item.name}
))}
Lazy Loading
컴포넌트를 필요할 때만 로드하여 초기 번들 크기를 줄이는 기법입니다. React.lazy()와 Suspense를 함께 사용합니다.
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
return (
로딩 중... }>
);
}Virtual Scrolling
대량의 데이터를 렌더링할 때 화면에 보이는 부분만 렌더링하여 성능을 최적화하는 기법입니다.
import { FixedSizeList as List } from 'react-window';
function VirtualizedList({ items }) {
const Row = ({ index, style }) => (
{items[index].name}
);
return (
-
{Row}