React Hooks는 함수형 컴포넌트에서 상태 관리와 생명주기 메서드를 사용할 수 있게 해주는 기능입니다. React 16.8에서 도입되었으며, 클래스 컴포넌트 없이도 React의 다양한 기능을 활용할 수 있게 해줍니다. 주요 훅으로는 useState, useEffect, useContext, useMemo, useCallback이 있으며, 개발자가 직접 커스텀 훅을 만들어 컴포넌트 로직을 재사용할 수도 있습니다.
오늘은 React 개발을 더 쉽고 효율적으로 만들어주는 React Hooks에 대해 알아보겠습니다!
React Hooks가 뭔가요? 🤔
여러분의 집에 다양한 스마트 기기들이 있다고 상상해보세요.
- 스마트 메모장은 중요한 정보를 기억합니다
- 스마트 비서는 특정 이벤트가 발생할 때 작업을 수행합니다
- 스마트 스피커는 집 전체에 정보를 공유합니다
React Hooks가 바로 이런 역할을 합니다!
- 함수형 컴포넌트에 다양한 기능을 쉽게 추가해주는 특별한 함수들
- 클래스 컴포넌트 없이도 React의 모든 기능을 사용할 수 있게 해주는 마법 ✨
어떻게 동작하나요? 🎬
1. useState - 스마트 메모장
import React, { useState } from 'react';
function Counter() {
// [현재값, 업데이트함수] = useState(초기값)
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>
증가
</button>
</div>
);
}
2. useEffect - 스마트 비서
import React, { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
// 컴포넌트가 렌더링된 후 실행됩니다
useEffect(() => {
// API에서 사용자 데이터 가져오기
fetch(`https://api.example.com/users/${userId}`)
.then(response => response.json())
.then(data => setUser(data));
// 컴포넌트가 언마운트될 때 정리 작업 수행
return () => {
console.log('컴포넌트 정리 중...');
};
}, [userId]); // userId가 변경될 때만 실행
if (!user) return <div>로딩 중...</div>;
return <div>{user.name}의 프로필</div>;
}
3. useContext - 스마트 스피커
import React, { useContext } from 'react';
// 컨텍스트 생성
const ThemeContext = React.createContext('light');
function App() {
// 상위 컴포넌트에서 컨텍스트 제공
return (
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
}
function ThemedButton() {
// 하위 컴포넌트에서 컨텍스트 사용
const theme = useContext(ThemeContext);
return <button className={theme}>테마 적용 버튼</button>;
}
4. useMemo - 스마트 계산기
import React, { useState, useMemo } from 'react';
function ExpensiveCalculation({ numbers }) {
// 복잡한 계산은 dependencies가 변경될 때만 재실행됩니다
const sum = useMemo(() => {
console.log('복잡한 계산 수행 중...');
return numbers.reduce((total, num) => total + num, 0);
}, [numbers]); // numbers가 변경될 때만 다시 계산
return <div>계산 결과: {sum}</div>;
}
5. useCallback - 스마트 리모컨
import React, { useState, useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
// 메모이제이션된 함수를 생성합니다
const handleClick = useCallback(() => {
console.log('버튼 클릭!');
setCount(prevCount => prevCount + 1);
}, []); // 의존성 배열이 비어있으므로 함수는 한 번만 생성됩니다
return (
<div>
<p>카운트: {count}</p>
<ChildComponent onClick={handleClick} />
</div>
);
}
function ChildComponent({ onClick }) {
console.log('자식 컴포넌트 렌더링');
return <button onClick={onClick}>클릭</button>;
}
장점은? 🌟
코드가 간결해져요
- 클래스 컴포넌트의 복잡한 생명주기 메서드 대신 직관적인 함수 사용
- this 바인딩 문제에서 해방!
로직 재사용이 쉬워요
- 커스텀 훅으로 컴포넌트 로직을 추출하여 재사용 가능
- 마치 레고 블록처럼 기능을 조립할 수 있어요
성능 최적화가 간편해요
- useMemo와 useCallback으로 불필요한 계산과 렌더링 방지
- 코드 품질과 앱 성능 향상
테스트가 더 쉬워졌어요
- 순수 함수 형태로 로직을 분리할 수 있어 테스트 용이
- 의존성 주입이 더 명확해짐
주의할 점 ⚠️
규칙을 지켜야 해요
- 훅은 항상 함수 컴포넌트의 최상위 레벨에서만 호출해야 함
- 조건문, 반복문, 중첩 함수 내에서 호출하면 안 됨
의존성 배열을 올바르게 설정하세요
- useEffect, useMemo, useCallback의 의존성 배열을 잘못 설정하면 버그 발생
- 빈 배열([])은 "마운트와 언마운트에만 실행"을 의미
너무 많은 상태는 관리하기 어려워요
- 복잡한 상태는 useReducer나 Context API와 함께 사용하는 것이 좋음
- 상태 관리 라이브러리(Redux, Recoil 등)도 고려해보세요
실제 사용 예시 📱
커스텀 훅 만들기
// 폼 입력 관리를 위한 커스텀 훅
function useInput(initialValue) {
const [value, setValue] = useState(initialValue);
// 입력 핸들러
const handleChange = (e) => {
setValue(e.target.value);
};
// 입력값 초기화
const reset = () => {
setValue(initialValue);
};
// 값과 핸들러를 객체로 반환
return {
value,
onChange: handleChange,
reset
};
}
// 커스텀 훅 사용 예시
function SignupForm() {
const name = useInput('');
const email = useInput('');
const handleSubmit = (e) => {
e.preventDefault();
console.log('제출된 데이터:', name.value, email.value);
name.reset();
email.reset();
};
return (
<form onSubmit={handleSubmit}>
<input placeholder="이름" {...name} />
<input placeholder="이메일" type="email" {...email} />
<button type="submit">가입하기</button>
</form>
);
}
로컬 스토리지와 함께 사용하기
// 로컬 스토리지와 연동하는 커스텀 훅
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 DarkModeToggle() {
const [darkMode, setDarkMode] = useLocalStorage('darkMode', false);
return (
<div className={darkMode ? 'dark' : 'light'}>
<button onClick={() => setDarkMode(!darkMode)}>
{darkMode ? '라이트 모드로 전환' : '다크 모드로 전환'}
</button>
</div>
);
}
마치며 🎁
React Hooks는 마치 여러분의 집에 있는 스마트 기기들처럼 React 개발을 더 쉽고 효율적으로 만들어줍니다. 클래스 컴포넌트의 복잡함에서 벗어나 더 직관적이고 재사용 가능한 코드를 작성할 수 있습니다. 초보자부터 전문가까지 누구나 활용할 수 있는 강력한 기능이니, 꼭 한번 시도해보세요!
궁금하신 점 있으시다면 댓글로 남겨주세요! 😊
참고 자료
- React 공식 문서 - Hooks API 참조: https://legacy.reactjs.org/docs/hooks-reference.html
- freeCodeCamp - React Hooks 사용 방법: https://www.freecodecamp.org/news/react-hooks-useeffect-usestate-and-usecontext/
- Walturn Insight - React Hooks 소개: https://www.walturn.com/insights/introduction-to-hooks-in-react
- W3Schools - React useMemo Hook: https://www.w3schools.com/react/react_usememo.asp
- React 공식 문서 - useCallback: https://react.dev/reference/react/useCallback
728x90
'400===Dev Library > React' 카테고리의 다른 글
React 실전 프로젝트 적용기: Todo 앱 만들기 📝 (0) | 2024.10.30 |
---|---|
React 개발자를 위한 핵심 개념 총정리 🎯 (1) | 2024.10.30 |
How does the virtual DOM improve performance? (0) | 2024.06.12 |
Create a simple React component that displays a message passed as a prop. (0) | 2024.06.12 |
React Component Lifecycle Explained (1) | 2024.06.10 |