React는 16.8 버전부터 Hooks라는 새로운 기능을 도입하여 함수형 컴포넌트에서도 상태 관리와 라이프사이클 메서드를 사용할 수 있게 했습니다.
이 글에서는 React Hooks의 기본 개념부터 고급 사용법까지 깊이 있게 다루고, 이를 활용해 효율적인 컴포넌트를 만드는 방법을 설명하겠습니다.
목차
- React Hooks란 무엇인가?
- 기본 Hooks
- useState
- useEffect
- useContext
- 추가 Hooks
- useReducer
- useCallback
- useMemo
- useRef
- useLayoutEffect
- 커스텀 Hooks 만들기
- Hooks 사용 시 유의할 점
- 결론
React Hooks란 무엇인가?
React Hooks는 클래스형 컴포넌트에서만 사용할 수 있었던 상태 관리와 라이프사이클 메서드를 함수형 컴포넌트에서도 사용할 수 있게 해주는 기능입니다.
이를 통해 코드가 더 간결해지고, 로직을 재사용하기 쉬워집니다.
기본 Hooks
useState
useState는 상태 변수를 선언하고 이를 업데이트할 수 있는 함수를 반환합니다.
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }
useEffect
useEffect는 사이드 이펙트를 수행할 수 있도록 해주는 Hook입니다. 예를 들어, 데이터 페칭, 구독, 수동으로 DOM을 변경하는 작업 등을 처리할 수 있습니다.
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }, [count]); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }
useContext
useContext는 Context API를 더 간편하게 사용할 수 있도록 해줍니다.
import React, { useContext } from 'react'; const ThemeContext = React.createContext('light'); function ThemedButton() { const theme = useContext(ThemeContext); return <button className={theme}>I am styled by theme context!</button>; }
추가 Hooks
useReducer
useReducer는 상태 관리 로직을 컴포넌트에서 분리할 수 있도록 도와줍니다. Redux와 비슷한 패턴을 따릅니다.
import React, { useReducer } from 'react'; const initialState = { count: 0 }; 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, initialState); return ( <div> <p>Count: {state.count}</p> <button onClick={() => dispatch({ type: 'increment' })}>+</button> <button onClick={() => dispatch({ type: 'decrement' })}>-</button> </div> ); }
useCallback
useCallback은 메모이제이션된 콜백을 반환합니다. 이 Hook은 컴포넌트가 불필요하게 다시 렌더링되는 것을 방지하는 데 유용합니다.
import React, { useState, useCallback } from 'react'; function Parent() { const [count, setCount] = useState(0); const increment = useCallback(() => { setCount(count + 1); }, [count]); return <Child increment={increment} />; } function Child({ increment }) { return <button onClick={increment}>Increment</button>; }
useMemo
useMemo는 메모이제이션된 값을 반환합니다. 이 Hook은 연산 비용이 높은 계산을 최적화하는 데 유용합니다.
import React, { useState, useMemo } from 'react'; function ExpensiveComponent({ a, b }) { const memoizedValue = useMemo(() => a + b, [a, b]); return <div>{memoizedValue}</div>; }
useRef
useRef는 변경 가능한 참조 객체를 생성합니다. 이 객체는 컴포넌트의 생애주기 동안 유지됩니다.
import React, { useRef } from 'react'; function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> <button onClick={onButtonClick}>Focus the input</button> </> ); }
useLayoutEffect
useLayoutEffect는 브라우저가 화면을 그리기 전에 동기적으로 실행됩니다. 이는 useEffect와 달리 레이아웃 측정 및 DOM 조작에 유용합니다.
import React, { useLayoutEffect, useRef } from 'react'; function LayoutEffectExample() { const ref = useRef(); useLayoutEffect(() => { console.log(ref.current.getBoundingClientRect()); }, []); return <div ref={ref}>Hello, world!</div>; }
커스텀 Hooks 만들기
커스텀 Hook은 반복되는 로직을 재사용할 수 있게 해줍니다. 예를 들어, 윈도우 사이즈를 추적하는 커스텀 Hook을 만들 수 있습니다.
import { useState, useEffect } from 'react'; function useWindowSize() { const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight, }); useEffect(() => { const handleResize = () => { setSize({ width: window.innerWidth, height: window.innerHeight, }); }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); return size; } function App() { const size = useWindowSize(); return ( <div> <p>Width: {size.width}</p> <p>Height: {size.height}</p> </div> ); }
Hooks 사용 시 유의할 점
Hook은 최상위 레벨에서만 호출 – Hook은 컴포넌트의 최상위 레벨에서만 호출해야 합니다. 루프, 조건문, 중첩된 함수 내에서 호출하지 않습니다.
React 함수형 컴포넌트에서만 사용 – Hook은 함수형 컴포넌트나 커스텀 Hook 내에서만 호출해야 합니다.
의존성 배열 관리 – useEffect, useCallback, useMemo등을 사용할 때 의존성 배열을 정확히 관리해야 합니다. 이를 통해 의도하지 않은 재렌더링을 방지할 수 있습니다.
결론
React Hooks는 컴포넌트를 더 간결하고 이해하기 쉽게 만들며, 상태 관리와 부수 효과를 함수형 컴포넌트에서 처리할 수 있도록 해줍니다. 기본 Hooks에서부터 커스텀 Hooks까지 다양한 사용법을 익히고, 이를 통해 효율적이고 재사용 가능한 컴포넌트를 만들어보세요.
이 가이드가 React Hooks를 이해하고 활용하는 데 도움이 되길 바랍니다.
Leave a Reply